<!DOCTYPE html>
<html lang="en">
<head>
  <title>Vert.x-Web - Vert.x</title>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta content="width=device-width, initial-scale=1.0" name="viewport">
  <meta content="Vert.x is a tool-kit for building reactive applications on the JVM." name="description">
  <link href="http://vertx.io/stylesheets/docs.css" media="screen" rel="stylesheet">
  <link href="http://vertx.io/stylesheets/font-awesome.min.css" media="screen" rel="stylesheet">
  <link href="http://vertx.io/javascripts/styles/rainbow.min.css" media="screen" rel="stylesheet">
  <!-- IE 6-8 support of HTML 5 elements -->
  <!--[if lt IE 9]>
  <script src="http://static.jboss.org/theme/js/libs/html5/pre3.6/html5.min.js"></script>
  <![endif]-->

  <link rel="apple-touch-icon" sizes="57x57" href="http://vertx.io/assets/favicons/vertx-favicon-7/apple-touch-icon-57x57.png">
  <link rel="apple-touch-icon" sizes="60x60" href="http://vertx.io/assets/favicons/vertx-favicon-7/apple-touch-icon-60x60.png">
  <link rel="apple-touch-icon" sizes="72x72" href="http://vertx.io/assets/favicons/vertx-favicon-7/apple-touch-icon-72x72.png">
  <link rel="apple-touch-icon" sizes="76x76" href="http://vertx.io/assets/favicons/vertx-favicon-7/apple-touch-icon-76x76.png">
  <link rel="apple-touch-icon" sizes="114x114" href="http://vertx.io/assets/favicons/vertx-favicon-7/apple-touch-icon-114x114.png">
  <link rel="apple-touch-icon" sizes="120x120" href="http://vertx.io/assets/favicons/vertx-favicon-7/apple-touch-icon-120x120.png">
  <link rel="apple-touch-icon" sizes="144x144" href="http://vertx.io/assets/favicons/vertx-favicon-7/apple-touch-icon-144x144.png">
  <link rel="apple-touch-icon" sizes="152x152" href="http://vertx.io/assets/favicons/vertx-favicon-7/apple-touch-icon-152x152.png">
  <link rel="apple-touch-icon" sizes="180x180" href="http://vertx.io/assets/favicons/vertx-favicon-7/apple-touch-icon-180x180.png">
  <link rel="icon" type="image/png" href="http://vertx.io/assets/favicons/vertx-favicon-7/favicon-32x32.png" sizes="32x32">
  <link rel="icon" type="image/png" href="http://vertx.io/assets/favicons/vertx-favicon-7/android-chrome-192x192.png" sizes="192x192">
  <link rel="icon" type="image/png" href="http://vertx.io/assets/favicons/vertx-favicon-7/favicon-96x96.png" sizes="96x96">
  <link rel="icon" type="image/png" href="http://vertx.io/assets/favicons/vertx-favicon-7/favicon-16x16.png" sizes="16x16">
  <link rel="manifest" href="http://vertx.io/assets/favicons/vertx-favicon-7/manifest.json">
  <link rel="mask-icon" href="http://vertx.io/assets/favicons/vertx-favicon-7/safari-pinned-tab.svg" color="#5bbad5">
  <meta name="msapplication-TileColor" content="#7d3194">
  <meta name="msapplication-TileImage" content="http://vertx.io/assets/favicons/vertx-favicon-7/mstile-144x144.png">
  <meta name="theme-color" content="#ffffff">

  <link href="http://fonts.googleapis.com/css?family=Ubuntu:400,500,700,400italic" rel="stylesheet" type="text/css">
  <link rel="alternate" type="application/rss+xml" title="RSS"
     href="http://vertx.io/feed.xml">
  <script>
    (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
      (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
      m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
    ga('create', 'UA-30144458-1', 'auto');
    ga('create', 'UA-71153120-1', 'auto', 'tracker');
    ga('send', 'pageview');
    ga('tracker.send', 'pageview');
  </script>
</head>
<body>

<a href="http://www.reactivemanifesto.org/" id="reactive-manifesto-banner">
  <img style="border: 0; position: fixed; right: 0; top:0; z-index: 9000"
    src="http://d379ifj7s9wntv.cloudfront.net/reactivemanifesto/images/ribbons/we-are-reactive-black-right.png">
</a>

<a id="skippy" class="sr-only sr-only-focusable" href="#content"><div class="container"><span class="skiplink-text">Skip to main content</span></div></a>

<header class="navbar navbar-default navbar-static-top" id="top" role="banner">
  <div class="container">
    <div class="navbar-header">
      <button class="navbar-toggle collapsed" type="button" data-toggle="collapse" data-target="#vertx-navbar-collapse">
        <span class="sr-only">Toggle navigation</span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </button>
      <a href="http://vertx.io/" class="navbar-brand"><img alt="Brand" src="http://vertx.io/assets/logo-sm.png"></a>
    </div>
    <nav class="collapse navbar-collapse" id="vertx-navbar-collapse">
      <ul class="nav navbar-nav navbar-right">
        <li><a href="http://vertx.io/download/">Download</a></li>
        <li><a href="http://vertx.io/docs/">Documentation</a></li>
        <li><a href="https://github.com/vert-x3/wiki/wiki">Wiki</a></li>
        <li><a href="http://vertx.io/community/">Community</a></li>
        <li><a href="http://vertx.io/materials/">Materials</a></li>
        <li><a href="http://vertx.io/blog/">Blog</a></li>        
      </ul>
    </nav>
  </div>
</header>



  <div class="page-header" id="content">
    <div class="container">
      <div class="row">
        <div class="col-sm-12">
          <h1>Vert.x-Web</h1>
          
        </div>
      </div>
    </div>
  </div>




<div id="content">
  <div class="container docs-content">
    <div class="row">
      <div class="col-sm-12 col-md-push-9 col-md-3 hidden-xs hidden-sm">
        <div id="sidebar" data-spy="affix">
          <ul class="sectlevel1">
<li><a href="#_using_vert_x_web">Using Vert.x Web</a></li>
<li><a href="#_re_cap_on_vert_x_core_http_servers">Re-cap on Vert.x core HTTP servers</a></li>
<li><a href="#_basic_vert_x_web_concepts">Basic Vert.x-Web concepts</a></li>
<li><a href="#_handling_requests_and_calling_the_next_handler">Handling requests and calling the next handler</a></li>
<li><a href="#_using_blocking_handlers">Using blocking handlers</a></li>
<li><a href="#_routing_by_exact_path">Routing by exact path</a></li>
<li><a href="#_routing_by_paths_that_begin_with_something">Routing by paths that begin with something</a></li>
<li><a href="#_capturing_path_parameters">Capturing path parameters</a></li>
<li><a href="#_routing_with_regular_expressions">Routing with regular expressions</a></li>
<li><a href="#_capturing_path_parameters_with_regular_expressions">Capturing path parameters with regular expressions</a></li>
<li><a href="#_routing_by_http_method">Routing by HTTP method</a></li>
<li><a href="#_route_order">Route order</a></li>
<li><a href="#_routing_based_on_mime_type_of_request">Routing based on MIME type of request</a></li>
<li><a href="#_routing_based_on_mime_types_acceptable_by_the_client">Routing based on MIME types acceptable by the client</a></li>
<li><a href="#_combining_routing_criteria">Combining routing criteria</a></li>
<li><a href="#_enabling_and_disabling_routes">Enabling and disabling routes</a></li>
<li><a href="#_context_data">Context data</a></li>
<li><a href="#_reroute">Reroute</a></li>
<li><a href="#_sub_routers">Sub-routers</a></li>
<li><a href="#_localization">Localization</a></li>
<li><a href="#_default_404_handling">Default 404 Handling</a></li>
<li><a href="#_error_handling">Error handling</a></li>
<li><a href="#_request_body_handling">Request body handling</a>
<ul class="sectlevel2">
<li><a href="#_getting_the_request_body">Getting the request body</a></li>
<li><a href="#_limiting_body_size">Limiting body size</a></li>
<li><a href="#_merging_form_attributes">Merging form attributes</a></li>
<li><a href="#_handling_file_uploads">Handling file uploads</a></li>
</ul>
</li>
<li><a href="#_handling_cookies">Handling cookies</a>
<ul class="sectlevel2">
<li><a href="#_manipulating_cookies">Manipulating cookies</a></li>
</ul>
</li>
<li><a href="#_handling_sessions">Handling sessions</a>
<ul class="sectlevel2">
<li><a href="#_session_stores">Session stores</a></li>
<li><a href="#_creating_the_session_handler">Creating the session handler</a></li>
<li><a href="#_using_the_session">Using the session</a></li>
<li><a href="#_session_timeout">Session timeout</a></li>
</ul>
</li>
<li><a href="#_authentication_authorisation">Authentication / authorisation</a>
<ul class="sectlevel2">
<li><a href="#_creating_an_auth_handler">Creating an auth handler</a></li>
<li><a href="#_handling_auth_in_your_application">Handling auth in your application</a></li>
<li><a href="#_http_basic_authentication">HTTP Basic Authentication</a></li>
<li><a href="#_redirect_auth_handler">Redirect auth handler</a></li>
<li><a href="#_jwt_authorisation">JWT authorisation</a></li>
<li><a href="#_configuring_required_authorities">Configuring required authorities</a></li>
</ul>
</li>
<li><a href="#_serving_static_resources">Serving static resources</a>
<ul class="sectlevel2">
<li><a href="#_configuring_caching">Configuring caching</a></li>
<li><a href="#_configuring_the_index_page">Configuring the index page</a></li>
<li><a href="#_changing_the_web_root">Changing the web root</a></li>
<li><a href="#_serving_hidden_files">Serving hidden files</a></li>
<li><a href="#_directory_listing">Directory listing</a></li>
<li><a href="#_disabling_file_caching_on_disk">Disabling file caching on disk</a></li>
</ul>
</li>
<li><a href="#_cors_handling">CORS handling</a></li>
<li><a href="#_templates">Templates</a>
<ul class="sectlevel2">
<li><a href="#_mvel_template_engine">MVEL template engine</a></li>
<li><a href="#_jade_template_engine">Jade template engine</a></li>
<li><a href="#_handlebars_template_engine">Handlebars template engine</a></li>
<li><a href="#_thymeleaf_template_engine">Thymeleaf template engine</a></li>
<li><a href="#_apache_freemarker_template_engine">Apache FreeMarker template engine</a></li>
</ul>
</li>
<li><a href="#_error_handler">Error handler</a></li>
<li><a href="#_request_logger">Request logger</a></li>
<li><a href="#_serving_favicons">Serving favicons</a></li>
<li><a href="#_timeout_handler">Timeout handler</a></li>
<li><a href="#_response_time_handler">Response time handler</a></li>
<li><a href="#_sockjs">SockJS</a>
<ul class="sectlevel2">
<li><a href="#_sockjs_handler">SockJS handler</a></li>
<li><a href="#_handling_sockjs_sockets">Handling SockJS sockets</a></li>
<li><a href="#_the_client_side">The client side</a></li>
<li><a href="#_configuring_the_sockjs_handler">Configuring the SockJS handler</a></li>
</ul>
</li>
<li><a href="#_sockjs_event_bus_bridge">SockJS event bus bridge</a>
<ul class="sectlevel2">
<li><a href="#_securing_the_bridge">Securing the Bridge</a></li>
<li><a href="#_requiring_authorisation_for_messages">Requiring authorisation for messages</a></li>
<li><a href="#_handling_event_bus_bridge_events">Handling event bus bridge events</a></li>
</ul>
</li>
<li><a href="#_csrf_cross_site_request_forgery">CSRF Cross Site Request Forgery</a></li>
<li><a href="#_virtualhost_handler">VirtualHost Handler</a></li>
<li><a href="#_oauth2authhandler_handler">OAuth2AuthHandler Handler</a></li>
</ul>
        </div>
      </div>
      <div class="col-sm-12 col-md-pull-3 col-md-9">
        <div class="toc hidden-md hidden-lg">
          <h2>Table of Contents</h2>
          <ul class="sectlevel1">
<li><a href="#_using_vert_x_web">Using Vert.x Web</a></li>
<li><a href="#_re_cap_on_vert_x_core_http_servers">Re-cap on Vert.x core HTTP servers</a></li>
<li><a href="#_basic_vert_x_web_concepts">Basic Vert.x-Web concepts</a></li>
<li><a href="#_handling_requests_and_calling_the_next_handler">Handling requests and calling the next handler</a></li>
<li><a href="#_using_blocking_handlers">Using blocking handlers</a></li>
<li><a href="#_routing_by_exact_path">Routing by exact path</a></li>
<li><a href="#_routing_by_paths_that_begin_with_something">Routing by paths that begin with something</a></li>
<li><a href="#_capturing_path_parameters">Capturing path parameters</a></li>
<li><a href="#_routing_with_regular_expressions">Routing with regular expressions</a></li>
<li><a href="#_capturing_path_parameters_with_regular_expressions">Capturing path parameters with regular expressions</a></li>
<li><a href="#_routing_by_http_method">Routing by HTTP method</a></li>
<li><a href="#_route_order">Route order</a></li>
<li><a href="#_routing_based_on_mime_type_of_request">Routing based on MIME type of request</a></li>
<li><a href="#_routing_based_on_mime_types_acceptable_by_the_client">Routing based on MIME types acceptable by the client</a></li>
<li><a href="#_combining_routing_criteria">Combining routing criteria</a></li>
<li><a href="#_enabling_and_disabling_routes">Enabling and disabling routes</a></li>
<li><a href="#_context_data">Context data</a></li>
<li><a href="#_reroute">Reroute</a></li>
<li><a href="#_sub_routers">Sub-routers</a></li>
<li><a href="#_localization">Localization</a></li>
<li><a href="#_default_404_handling">Default 404 Handling</a></li>
<li><a href="#_error_handling">Error handling</a></li>
<li><a href="#_request_body_handling">Request body handling</a>
<ul class="sectlevel2">
<li><a href="#_getting_the_request_body">Getting the request body</a></li>
<li><a href="#_limiting_body_size">Limiting body size</a></li>
<li><a href="#_merging_form_attributes">Merging form attributes</a></li>
<li><a href="#_handling_file_uploads">Handling file uploads</a></li>
</ul>
</li>
<li><a href="#_handling_cookies">Handling cookies</a>
<ul class="sectlevel2">
<li><a href="#_manipulating_cookies">Manipulating cookies</a></li>
</ul>
</li>
<li><a href="#_handling_sessions">Handling sessions</a>
<ul class="sectlevel2">
<li><a href="#_session_stores">Session stores</a></li>
<li><a href="#_creating_the_session_handler">Creating the session handler</a></li>
<li><a href="#_using_the_session">Using the session</a></li>
<li><a href="#_session_timeout">Session timeout</a></li>
</ul>
</li>
<li><a href="#_authentication_authorisation">Authentication / authorisation</a>
<ul class="sectlevel2">
<li><a href="#_creating_an_auth_handler">Creating an auth handler</a></li>
<li><a href="#_handling_auth_in_your_application">Handling auth in your application</a></li>
<li><a href="#_http_basic_authentication">HTTP Basic Authentication</a></li>
<li><a href="#_redirect_auth_handler">Redirect auth handler</a></li>
<li><a href="#_jwt_authorisation">JWT authorisation</a></li>
<li><a href="#_configuring_required_authorities">Configuring required authorities</a></li>
</ul>
</li>
<li><a href="#_serving_static_resources">Serving static resources</a>
<ul class="sectlevel2">
<li><a href="#_configuring_caching">Configuring caching</a></li>
<li><a href="#_configuring_the_index_page">Configuring the index page</a></li>
<li><a href="#_changing_the_web_root">Changing the web root</a></li>
<li><a href="#_serving_hidden_files">Serving hidden files</a></li>
<li><a href="#_directory_listing">Directory listing</a></li>
<li><a href="#_disabling_file_caching_on_disk">Disabling file caching on disk</a></li>
</ul>
</li>
<li><a href="#_cors_handling">CORS handling</a></li>
<li><a href="#_templates">Templates</a>
<ul class="sectlevel2">
<li><a href="#_mvel_template_engine">MVEL template engine</a></li>
<li><a href="#_jade_template_engine">Jade template engine</a></li>
<li><a href="#_handlebars_template_engine">Handlebars template engine</a></li>
<li><a href="#_thymeleaf_template_engine">Thymeleaf template engine</a></li>
<li><a href="#_apache_freemarker_template_engine">Apache FreeMarker template engine</a></li>
</ul>
</li>
<li><a href="#_error_handler">Error handler</a></li>
<li><a href="#_request_logger">Request logger</a></li>
<li><a href="#_serving_favicons">Serving favicons</a></li>
<li><a href="#_timeout_handler">Timeout handler</a></li>
<li><a href="#_response_time_handler">Response time handler</a></li>
<li><a href="#_sockjs">SockJS</a>
<ul class="sectlevel2">
<li><a href="#_sockjs_handler">SockJS handler</a></li>
<li><a href="#_handling_sockjs_sockets">Handling SockJS sockets</a></li>
<li><a href="#_the_client_side">The client side</a></li>
<li><a href="#_configuring_the_sockjs_handler">Configuring the SockJS handler</a></li>
</ul>
</li>
<li><a href="#_sockjs_event_bus_bridge">SockJS event bus bridge</a>
<ul class="sectlevel2">
<li><a href="#_securing_the_bridge">Securing the Bridge</a></li>
<li><a href="#_requiring_authorisation_for_messages">Requiring authorisation for messages</a></li>
<li><a href="#_handling_event_bus_bridge_events">Handling event bus bridge events</a></li>
</ul>
</li>
<li><a href="#_csrf_cross_site_request_forgery">CSRF Cross Site Request Forgery</a></li>
<li><a href="#_virtualhost_handler">VirtualHost Handler</a></li>
<li><a href="#_oauth2authhandler_handler">OAuth2AuthHandler Handler</a></li>
</ul>
        </div>
        <div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>Vert.x-Web is a set of building blocks for building web applications with Vert.x.</p>
</div>
<div class="paragraph">
<p>Think of it as a Swiss Army Knife for building
modern, scalable, web apps.</p>
</div>
<div class="paragraph">
<p>Vert.x core provides a fairly low level set of functionality for handling HTTP, and for some applications
that will be sufficient.</p>
</div>
<div class="paragraph">
<p>Vert.x-Web builds on Vert.x core to provide a richer set of functionality for building real web applications, more
easily.</p>
</div>
<div class="paragraph">
<p>It&#8217;s the successor to <a href="http://pmlopes.github.io/yoke/">Yoke</a> in Vert.x 2.x, and takes inspiration from projects such
as <a href="http://expressjs.com/">Express</a> in the Node.js world and <a href="http://www.sinatrarb.com/">Sinatra</a> in the Ruby world.</p>
</div>
<div class="paragraph">
<p>Vert.x-Web is designed to be powerful, un-opionated and fully embeddable. You just use the parts you want and nothing more.
Vert.x-Web is not a container.</p>
</div>
<div class="paragraph">
<p>You can use Vert.x-Web to create classic server-side web applications, RESTful web applications, 'real-time' (server push)
web applications, or any other kind of web application you can think of. Vert.x-Web doesn&#8217;t care. It&#8217;s up to you to chose
the type of app you prefer, not Vert.x-Web.</p>
</div>
<div class="paragraph">
<p>Vert.x-Web is a great fit for writing <strong>RESTful HTTP micro-services</strong>, but we don&#8217;t <strong>force</strong> you to write apps like that.</p>
</div>
<div class="paragraph">
<p>Some of the key features of Vert.x-Web include:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Routing (based on method, path, etc)</p>
</li>
<li>
<p>Regular expression pattern matching for paths</p>
</li>
<li>
<p>Extraction of parameters from paths</p>
</li>
<li>
<p>Content negotiation</p>
</li>
<li>
<p>Request body handling</p>
</li>
<li>
<p>Body size limits</p>
</li>
<li>
<p>Cookie parsing and handling</p>
</li>
<li>
<p>Multipart forms</p>
</li>
<li>
<p>Multipart file uploads</p>
</li>
<li>
<p>Sub routers</p>
</li>
<li>
<p>Session support - both local (for sticky sessions) and clustered (for non sticky)</p>
</li>
<li>
<p>CORS (Cross Origin Resource Sharing) support</p>
</li>
<li>
<p>Error page handler</p>
</li>
<li>
<p>Basic Authentication</p>
</li>
<li>
<p>Redirect based authentication</p>
</li>
<li>
<p>Authorisation handlers</p>
</li>
<li>
<p>JWT based authorization</p>
</li>
<li>
<p>User/role/permission authorisation</p>
</li>
<li>
<p>Favicon handling</p>
</li>
<li>
<p>Template support for server side rendering, including support for the following template engines out of the box:</p>
<div class="ulist">
<ul>
<li>
<p>Handlebars</p>
</li>
<li>
<p>Jade,</p>
</li>
<li>
<p>MVEL</p>
</li>
<li>
<p>Thymeleaf</p>
</li>
<li>
<p>Apache FreeMarker</p>
</li>
</ul>
</div>
</li>
<li>
<p>Response time handler</p>
</li>
<li>
<p>Static file serving, including caching logic and directory listing.</p>
</li>
<li>
<p>Request timeout support</p>
</li>
<li>
<p>SockJS support</p>
</li>
<li>
<p>Event-bus bridge</p>
</li>
<li>
<p>CSRF Cross Site Request Forgery</p>
</li>
<li>
<p>VirtualHost</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Most features in Vert.x-Web are implemented as handlers so you can always write your own. We envisage many more being written
over time.</p>
</div>
<div class="paragraph">
<p>We&#8217;ll discuss all these features in this manual.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_using_vert_x_web">Using Vert.x Web</h2>
<div class="sectionbody">
<div class="paragraph">
<p>To use vert.x web, add the following dependency to the <em>dependencies</em> section of your build descriptor:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Maven (in your <code>pom.xml</code>):</p>
</li>
</ul>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-xml" data-lang="xml">&lt;dependency&gt;
  &lt;groupId&gt;io.vertx&lt;/groupId&gt;
  &lt;artifactId&gt;vertx-web&lt;/artifactId&gt;
  &lt;version&gt;3.3.3&lt;/version&gt;
&lt;/dependency&gt;</code></pre>
</div>
</div>
<div class="ulist">
<ul>
<li>
<p>Gradle (in your <code>build.gradle</code> file):</p>
</li>
</ul>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-groovy" data-lang="groovy">dependencies {
  compile 'io.vertx:vertx-web:3.3.3'
}</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_re_cap_on_vert_x_core_http_servers">Re-cap on Vert.x core HTTP servers</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Vert.x-Web uses and exposes the API from Vert.x core, so it&#8217;s well worth getting familiar with the basic concepts of writing
HTTP servers using Vert.x core, if you&#8217;re not already.</p>
</div>
<div class="paragraph">
<p>The Vert.x core HTTP documentation goes into a lot of detail on this.</p>
</div>
<div class="paragraph">
<p>Here&#8217;s a hello world web server written using Vert.x core. At this point there is no Vert.x-Web involved:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">server = vertx.create_http_server()

server.request_handler() { |request|

  # This handler gets called for each request that arrives on the server
  response = request.response()
  response.put_header("content-type", "text/plain")

  # Write to the response and end it
  response.end("Hello World!")
}

server.listen(8080)</code></pre>
</div>
</div>
<div class="paragraph">
<p>We create an HTTP server instance, and we set a request handler on it. The request handler will be called whenever
a request arrives on the server.</p>
</div>
<div class="paragraph">
<p>When that happens we are just going to set the content type to <code>text/plain</code>, and write <code>Hello World!</code> and end the
response.</p>
</div>
<div class="paragraph">
<p>We then tell the server to listen at port <code>8080</code> (default host is <code>localhost</code>).</p>
</div>
<div class="paragraph">
<p>You can run this, and point your browser at <code><a href="http://localhost:8080" class="bare">http://localhost:8080</a></code> to verify that it works as expected.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_basic_vert_x_web_concepts">Basic Vert.x-Web concepts</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Here&#8217;s the 10000 foot view:</p>
</div>
<div class="paragraph">
<p>A <code><a href="../../yardoc/VertxWeb/Router.html">Router</a></code> is one of the core concepts of Vert.x-Web. It&#8217;s an object which maintains zero or more
<code><a href="../../yardoc/VertxWeb/Route.html">Routes</a></code> .</p>
</div>
<div class="paragraph">
<p>A router takes an HTTP request and finds the first matching route for that request, and passes the request to that route.</p>
</div>
<div class="paragraph">
<p>The route can have a <em>handler</em> associated with it, which then receives the request. You then <em>do something</em> with the
request, and then, either end it or pass it to the next matching handler.</p>
</div>
<div class="paragraph">
<p>Here&#8217;s a simple router example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx-web/router'
server = vertx.create_http_server()

router = VertxWeb::Router.router(vertx)

router.route().handler() { |routingContext|

  # This handler will be called for every request
  response = routingContext.response()
  response.put_header("content-type", "text/plain")

  # Write to the response and end it
  response.end("Hello World from Vert.x-Web!")
}

server.request_handler(&amp;router.method(:accept)).listen(8080)</code></pre>
</div>
</div>
<div class="paragraph">
<p>It basically does the same thing as the Vert.x Core HTTP server hello world example from the previous section,
but this time using Vert.x-Web.</p>
</div>
<div class="paragraph">
<p>We create an HTTP server as before, then we create a router. Once we&#8217;ve done that we create a simple route with
no matching criteria so it will match <em>all</em> requests that arrive on the server.</p>
</div>
<div class="paragraph">
<p>We then specify a handler for that route. That handler will be called for all requests that arrive on the server.</p>
</div>
<div class="paragraph">
<p>The object that gets passed into the handler is a <code><a href="../../yardoc/VertxWeb/RoutingContext.html">RoutingContext</a></code> - this contains
the standard Vert.x <code><a href="../../yardoc/Vertx/HttpServerRequest.html">HttpServerRequest</a></code> and <code><a href="../../yardoc/Vertx/HttpServerResponse.html">HttpServerResponse</a></code>
but also various other useful stuff that makes working with Vert.x-Web simpler.</p>
</div>
<div class="paragraph">
<p>For every request that is routed there is a unique routing context instance, and the same instance is passed to
all handlers for that request.</p>
</div>
<div class="paragraph">
<p>Once we&#8217;ve set up the handler, we set the request handler of the HTTP server to pass all incoming requests
to <code><a href="../../yardoc/VertxWeb/Router.html#accept-instance_method">accept</a></code>.</p>
</div>
<div class="paragraph">
<p>So, that&#8217;s the basics. Now we&#8217;ll look at things in more detail:</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_handling_requests_and_calling_the_next_handler">Handling requests and calling the next handler</h2>
<div class="sectionbody">
<div class="paragraph">
<p>When Vert.x-Web decides to route a request to a matching route, it calls the handler of the route passing in an instance
of <code><a href="../../yardoc/VertxWeb/RoutingContext.html">RoutingContext</a></code>.</p>
</div>
<div class="paragraph">
<p>If you don&#8217;t end the response in your handler, you should call <code><a href="../../yardoc/VertxWeb/RoutingContext.html#next-instance_method">next</a></code> so another
matching route can handle the request (if any).</p>
</div>
<div class="paragraph">
<p>You don&#8217;t have to call <code><a href="../../yardoc/VertxWeb/RoutingContext.html#next-instance_method">next</a></code> before the handler has finished executing.
You can do this some time later, if you want:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">route1 = router.route("/some/path/").handler() { |routingContext|

  response = routingContext.response()
  # enable chunked responses because we will be adding data as
  # we execute over other handlers. This is only required once and
  # only if several handlers do output.
  response.set_chunked(true)

  response.write("route1\n")

  # Call the next matching route after a 5 second delay
  routingContext.vertx().set_timer(5000) { |tid|
    routingContext.next()
  }
}

route2 = router.route("/some/path/").handler() { |routingContext|

  response = routingContext.response()
  response.write("route2\n")

  # Call the next matching route after a 5 second delay
  routingContext.vertx().set_timer(5000) { |tid|
    routingContext.next()
  }
}

route3 = router.route("/some/path/").handler() { |routingContext|

  response = routingContext.response()
  response.write("route3")

  # Now end the response
  routingContext.response().end()
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>In the above example <code>route1</code> is written to the response, then 5 seconds later <code>route2</code> is written to the response,
then 5 seconds later <code>route3</code> is written to the response and the response is ended.</p>
</div>
<div class="paragraph">
<p>Note, all this happens without any thread blocking.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_using_blocking_handlers">Using blocking handlers</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Sometimes, you might have to do something in a handler that might block the event loop for some time, e.g. call
a legacy blocking API or do some intensive calculation.</p>
</div>
<div class="paragraph">
<p>You can&#8217;t do that in a normal handler, so we provide the ability to set blocking handlers on a route.</p>
</div>
<div class="paragraph">
<p>A blocking handler looks just like a normal handler but it&#8217;s called by Vert.x using a thread from the worker pool
not using an event loop.</p>
</div>
<div class="paragraph">
<p>You set a blocking handler on a route with <code><a href="../../yardoc/VertxWeb/Route.html#blocking_handler-instance_method">blockingHandler</a></code>.
Here&#8217;s an example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">router.route().blocking_handler() { |routingContext|

  # Do something that might take some time synchronously
  service.do_something_that_blocks()

  # Now call the next handler
  routingContext.next()

}</code></pre>
</div>
</div>
<div class="paragraph">
<p>By default, any blocking handlers executed on the same context (e.g. the same verticle instance) are <em>ordered</em> - this
means the next one won&#8217;t be executed until the previous one has completed. If you don&#8217;t care about orderering and
don&#8217;t mind your blocking handlers executing in parallel you can set the blocking handler specifying <code>ordered</code> as
false using <code><a href="../../yardoc/VertxWeb/Route.html#blocking_handler-instance_method">blockingHandler</a></code>.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_routing_by_exact_path">Routing by exact path</h2>
<div class="sectionbody">
<div class="paragraph">
<p>A route can be set-up to match the path from the request URI. In this case it will match any request which has a path
that&#8217;s the same as the specified path.</p>
</div>
<div class="paragraph">
<p>In the following example the handler will be called for a request <code>/some/path/</code>. We also ignore trailing slashes
so it will be called for paths <code>/some/path</code> and <code>/some/path//</code> too:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">route = router.route().path("/some/path/")

route.handler() { |routingContext|
  # This handler will be called for the following request paths:

  # `/some/path`
  # `/some/path/`
  # `/some/path//`
  #
  # but not:
  # `/some/path/subdir`
}</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_routing_by_paths_that_begin_with_something">Routing by paths that begin with something</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Often you want to route all requests that begin with a certain path. You could use a regex to do this, but a simply
way is to use an asterisk <code>*</code> at the end of the path when declaring the route path.</p>
</div>
<div class="paragraph">
<p>In the following example the handler will be called for any request with a URI path that starts with
<code>/some/path/</code>.</p>
</div>
<div class="paragraph">
<p>For example <code>/some/path/foo.html</code> and <code>/some/path/otherdir/blah.css</code> would both match.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">route = router.route().path("/some/path/*")

route.handler() { |routingContext|
  # This handler will be called for any path that starts with
  # `/some/path/`, e.g.

  # `/some/path`
  # `/some/path/`
  # `/some/path/subdir`
  # `/some/path/subdir/blah.html`
  #
  # but not:
  # `/some/bath`
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>With any path it can also be specified when creating the route:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">route = router.route("/some/path/*")

route.handler() { |routingContext|
  # This handler will be called same as previous example
}</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_capturing_path_parameters">Capturing path parameters</h2>
<div class="sectionbody">
<div class="paragraph">
<p>It&#8217;s possible to match paths using placeholders for parameters which are then available in the request
<code><a href="../../yardoc/Vertx/HttpServerRequest.html#params-instance_method">params</a></code>.</p>
</div>
<div class="paragraph">
<p>Here&#8217;s an example</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">route = router.route(:POST, "/catalogue/products/:productype/:productid/")

route.handler() { |routingContext|

  productType = routingContext.request().get_param("producttype")
  productID = routingContext.request().get_param("productid")

  # Do something with them...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The placeholders consist of <code>:</code> followed by the parameter name. Parameter names consist of any alphabetic character,
numeric character or underscore.</p>
</div>
<div class="paragraph">
<p>In the above example, if a POST request is made to path: <code>/catalogue/products/tools/drill123/</code> then the route will match
and <code>productType</code> will receive the value <code>tools</code> and productID will receive the value <code>drill123</code>.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_routing_with_regular_expressions">Routing with regular expressions</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Regular expressions can also be used to match URI paths in routes.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby"># Matches any path ending with 'foo'
route = router.route().path_regex(".*foo")

route.handler() { |routingContext|

  # This handler will be called for:

  # /some/path/foo
  # /foo
  # /foo/bar/wibble/foo
  # /foo/bar

  # But not:
  # /bar/wibble
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Alternatively the regex can be specified when creating the route:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">route = router.route_with_regex(".*foo")

route.handler() { |routingContext|

  # This handler will be called same as previous example

}</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_capturing_path_parameters_with_regular_expressions">Capturing path parameters with regular expressions</h2>
<div class="sectionbody">
<div class="paragraph">
<p>You can also capture path parameters when using regular expressions, here&#8217;s an example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">route = router.route_with_regex(".*foo")

# This regular expression matches paths that start with something like:
# "/foo/bar" - where the "foo" is captured into param0 and the "bar" is captured into
# param1
route.path_regex("\\/([^\\/]+)\\/([^\\/]+)").handler() { |routingContext|

  productType = routingContext.request().get_param("param0")
  productID = routingContext.request().get_param("param1")

  # Do something with them...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>In the above example, if a request is made to path: <code>/tools/drill123/</code> then the route will match
and <code>productType</code> will receive the value <code>tools</code> and productID will receive the value <code>drill123</code>.</p>
</div>
<div class="paragraph">
<p>Captures are denoted in regular expressions with capture groups (i.e. surrounding the capture with round brackets)</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_routing_by_http_method">Routing by HTTP method</h2>
<div class="sectionbody">
<div class="paragraph">
<p>By default a route will match all HTTP methods.</p>
</div>
<div class="paragraph">
<p>If you want a route to only match for a specific HTTP method you can use <code><a href="../../yardoc/VertxWeb/Route.html#method-instance_method">method</a></code></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">route = router.route().method(:POST)

route.handler() { |routingContext|

  # This handler will be called for any POST request

}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Or you can specify this with a path when creating the route:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">route = router.route(:POST, "/some/path/")

route.handler() { |routingContext|

  # This handler will be called for any POST request to a URI path starting with /some/path/

}</code></pre>
</div>
</div>
<div class="paragraph">
<p>If you want to route for a specific HTTP method you can also use the methods such as <code><a href="../../yardoc/VertxWeb/Router.html#get-instance_method">get</a></code>,
<code><a href="../../yardoc/VertxWeb/Router.html#post-instance_method">post</a></code> and <code><a href="../../yardoc/VertxWeb/Router.html#put-instance_method">put</a></code> named after the HTTP
method name. For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">router.get().handler() { |routingContext|

  # Will be called for any GET request

}

router.get("/some/path/").handler() { |routingContext|

  # Will be called for any GET request to a path
  # starting with /some/path

}

router.get_with_regex(".*foo").handler() { |routingContext|

  # Will be called for any GET request to a path
  # ending with `foo`

}

# There are also equivalents to the above for PUT, POST, DELETE, HEAD and OPTIONS</code></pre>
</div>
</div>
<div class="paragraph">
<p>If you want to specify a route will match for more than HTTP method you can call <code><a href="../../yardoc/VertxWeb/Route.html#method-instance_method">method</a></code>
multiple times:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">route = router.route().method(:POST).method(:PUT)

route.handler() { |routingContext|

  # This handler will be called for any POST or PUT request

}</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_route_order">Route order</h2>
<div class="sectionbody">
<div class="paragraph">
<p>By default routes are matched in the order they are added to the router.</p>
</div>
<div class="paragraph">
<p>When a request arrives the router will step through each route and check if it matches, if it matches then
the handler for that route will be called.</p>
</div>
<div class="paragraph">
<p>If the handler subsequently calls <code><a href="../../yardoc/VertxWeb/RoutingContext.html#next-instance_method">next</a></code> the handler for the next
matching route (if any) will be called. And so on.</p>
</div>
<div class="paragraph">
<p>Here&#8217;s an example to illustrate this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">route1 = router.route("/some/path/").handler() { |routingContext|

  response = routingContext.response()
  # enable chunked responses because we will be adding data as
  # we execute over other handlers. This is only required once and
  # only if several handlers do output.
  response.set_chunked(true)

  response.write("route1\n")

  # Now call the next matching route
  routingContext.next()
}

route2 = router.route("/some/path/").handler() { |routingContext|

  response = routingContext.response()
  response.write("route2\n")

  # Now call the next matching route
  routingContext.next()
}

route3 = router.route("/some/path/").handler() { |routingContext|

  response = routingContext.response()
  response.write("route3")

  # Now end the response
  routingContext.response().end()
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>In the above example the response will contain:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>route1
route2
route3</pre>
</div>
</div>
<div class="paragraph">
<p>As the routes have been called in that order for any request that starts with <code>/some/path</code>.</p>
</div>
<div class="paragraph">
<p>If you want to override the default ordering for routes, you can do so using <code><a href="../../yardoc/VertxWeb/Route.html#order-instance_method">order</a></code>,
specifying an integer value.</p>
</div>
<div class="paragraph">
<p>Routes are assigned an order at creation time corresponding to the order in which they were added to the router, with
the first route numbered <code>0</code>, the second route numbered <code>1</code>, and so on.</p>
</div>
<div class="paragraph">
<p>By specifying an order for the route you can override the default ordering. Order can also be negative, e.g. if you
want to ensure a route is evaluated before route number <code>0</code>.</p>
</div>
<div class="paragraph">
<p>Let&#8217;s change the ordering of route2 so it runs before route1:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">route1 = router.route("/some/path/").handler() { |routingContext|

  response = routingContext.response()
  response.write("route1\n")

  # Now call the next matching route
  routingContext.next()
}

route2 = router.route("/some/path/").handler() { |routingContext|

  response = routingContext.response()
  # enable chunked responses because we will be adding data as
  # we execute over other handlers. This is only required once and
  # only if several handlers do output.
  response.set_chunked(true)

  response.write("route2\n")

  # Now call the next matching route
  routingContext.next()
}

route3 = router.route("/some/path/").handler() { |routingContext|

  response = routingContext.response()
  response.write("route3")

  # Now end the response
  routingContext.response().end()
}

# Change the order of route2 so it runs before route1
route2.order(-1)</code></pre>
</div>
</div>
<div class="paragraph">
<p>then the response will now contain:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>route2
route1
route3</pre>
</div>
</div>
<div class="paragraph">
<p>If two matching routes have the same value of order, then they will be called in the order they were added.</p>
</div>
<div class="paragraph">
<p>You can also specify that a route is handled last, with <code><a href="../../yardoc/VertxWeb/Route.html#last-instance_method">last</a></code></p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_routing_based_on_mime_type_of_request">Routing based on MIME type of request</h2>
<div class="sectionbody">
<div class="paragraph">
<p>You can specify that a route will match against matching request MIME types using <code><a href="../../yardoc/VertxWeb/Route.html#consumes-instance_method">consumes</a></code>.</p>
</div>
<div class="paragraph">
<p>In this case, the request will contain a <code>content-type</code> header specifying the MIME type of the request body.
This will be matched against the value specified in <code><a href="../../yardoc/VertxWeb/Route.html#consumes-instance_method">consumes</a></code>.</p>
</div>
<div class="paragraph">
<p>Basically, <code>consumes</code> is describing which MIME types the handler can <em>consume</em>.</p>
</div>
<div class="paragraph">
<p>Matching can be done on exact MIME type matches:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby"># Exact match
router.route().consumes("text/html").handler() { |routingContext|

  # This handler will be called for any request with
  # content-type header set to `text/html`

}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Multiple exact matches can also be specified:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby"># Multiple exact matches
router.route().consumes("text/html").consumes("text/plain").handler() { |routingContext|

  # This handler will be called for any request with
  # content-type header set to `text/html` or `text/plain`.

}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Matching on wildcards for the sub-type is supported:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby"># Sub-type wildcard match
router.route().consumes("text/*").handler() { |routingContext|

  # This handler will be called for any request with top level type `text`
  # e.g. content-type header set to `text/html` or `text/plain` will both match

}</code></pre>
</div>
</div>
<div class="paragraph">
<p>And you can also match on the top level type</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby"># Top level type wildcard match
router.route().consumes("*/json").handler() { |routingContext|

  # This handler will be called for any request with sub-type json
  # e.g. content-type header set to `text/json` or `application/json` will both match

}</code></pre>
</div>
</div>
<div class="paragraph">
<p>If you don&#8217;t specify a <code>/</code> in the consumers, it will assume you meant the sub-type.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_routing_based_on_mime_types_acceptable_by_the_client">Routing based on MIME types acceptable by the client</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The HTTP <code>accept</code> header is used to signify which MIME types of the response are acceptable to the client.</p>
</div>
<div class="paragraph">
<p>An <code>accept</code> header can have multiple MIME types separated by &#8216;,&#8217;.</p>
</div>
<div class="paragraph">
<p>MIME types can also have a <code>q</code> value appended to them* which signifies a weighting to apply if more than one
response MIME type is available matching the accept header. The q value is a number between 0 and 1.0.
If omitted it defaults to 1.0.</p>
</div>
<div class="paragraph">
<p>For example, the following <code>accept</code> header signifies the client will accept a MIME type of only <code>text/plain</code>:</p>
</div>
<div class="literalblock">
<div class="content">
<pre>Accept: text/plain</pre>
</div>
</div>
<div class="paragraph">
<p>With the following the client will accept <code>text/plain</code> or <code>text/html</code> with no preference.</p>
</div>
<div class="literalblock">
<div class="content">
<pre>Accept: text/plain, text/html</pre>
</div>
</div>
<div class="paragraph">
<p>With the following the client will accept <code>text/plain</code> or <code>text/html</code> but prefers <code>text/html</code> as it has a higher
<code>q</code> value (the default value is q=1.0)</p>
</div>
<div class="literalblock">
<div class="content">
<pre>Accept: text/plain; q=0.9, text/html</pre>
</div>
</div>
<div class="paragraph">
<p>If the server can provide both text/plain and text/html it should provide the text/html in this case.</p>
</div>
<div class="paragraph">
<p>By using <code><a href="../../yardoc/VertxWeb/Route.html#produces-instance_method">produces</a></code> you define which MIME type(s) the route produces, e.g. the
following handler produces a response with MIME type <code>application/json</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">router.route().produces("application/json").handler() { |routingContext|

  response = routingContext.response()
  response.put_header("content-type", "application/json")
  response.write(someJSON).end()

}</code></pre>
</div>
</div>
<div class="paragraph">
<p>In this case the route will match with any request with an <code>accept</code> header that matches <code>application/json</code>.</p>
</div>
<div class="paragraph">
<p>Here are some examples of <code>accept</code> headers that will match:</p>
</div>
<div class="literalblock">
<div class="content">
<pre>Accept: application/json
Accept: application/*
Accept: application/json, text/html
Accept: application/json;q=0.7, text/html;q=0.8, text/plain</pre>
</div>
</div>
<div class="paragraph">
<p>You can also mark your route as producing more than one MIME type. If this is the case, then you use
<code><a href="../../yardoc/VertxWeb/RoutingContext.html#get_acceptable_content_type-instance_method">getAcceptableContentType</a></code> to find out the actual MIME type that
was accepted.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby"># This route can produce two different MIME types
router.route().produces("application/json").produces("text/html").handler() { |routingContext|

  response = routingContext.response()

  # Get the actual MIME type acceptable
  acceptableContentType = routingContext.get_acceptable_content_type()

  response.put_header("content-type", acceptableContentType)
  response.write(whatever).end()
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>In the above example, if you sent a request with the following <code>accept</code> header:</p>
</div>
<div class="literalblock">
<div class="content">
<pre>Accept: application/json; q=0.7, text/html</pre>
</div>
</div>
<div class="paragraph">
<p>Then the route would match and <code>acceptableContentType</code> would contain <code>text/html</code> as both are
acceptable but that has a higher <code>q</code> value.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_combining_routing_criteria">Combining routing criteria</h2>
<div class="sectionbody">
<div class="paragraph">
<p>You can combine all the above routing criteria in many different ways, for example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">route = router.route(:PUT, "myapi/orders").consumes("application/json").produces("application/json")

route.handler() { |routingContext|

  # This would be match for any PUT method to paths starting with "myapi/orders" with a
  # content-type of "application/json"
  # and an accept header matching "application/json"

}</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_enabling_and_disabling_routes">Enabling and disabling routes</h2>
<div class="sectionbody">
<div class="paragraph">
<p>You can disable a route with <code><a href="../../yardoc/VertxWeb/Route.html#disable-instance_method">disable</a></code>. A disabled route will be ignored when matching.</p>
</div>
<div class="paragraph">
<p>You can re-enable a disabled route with <code><a href="../../yardoc/VertxWeb/Route.html#enable-instance_method">enable</a></code></p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_context_data">Context data</h2>
<div class="sectionbody">
<div class="paragraph">
<p>You can use the context data in the <code><a href="../../yardoc/VertxWeb/RoutingContext.html">RoutingContext</a></code> to maintain any data that you
want to share between handlers for the lifetime of the request.</p>
</div>
<div class="paragraph">
<p>Here&#8217;s an example where one handler sets some data in the context data and a subsequent handler retrieves it:</p>
</div>
<div class="paragraph">
<p>You can use the <code><a href="../../yardoc/VertxWeb/RoutingContext.html#put-instance_method">put</a></code> to put any object, and
<code><a href="../../yardoc/VertxWeb/RoutingContext.html#get-instance_method">get</a></code> to retrieve any object from the context data.</p>
</div>
<div class="paragraph">
<p>A request sent to path <code>/some/path/other</code> will match both routes.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">router.get("/some/path").handler() { |routingContext|

  routingContext.put("foo", "bar")
  routingContext.next()

}

router.get("/some/path/other").handler() { |routingContext|

  bar = routingContext.get("foo")
  # Do something with bar
  routingContext.response().end()

}</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_reroute">Reroute</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Until now all routing mechanism allow you to handle your requests in a sequential way, however there might be times
where you will want to go back. Since the context does not expose any information about the previous or next handler,
mostly because this information is dynamic there is a way to restart the whole routing from the start of the current
Router.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">router.get("/some/path").handler() { |routingContext|

  routingContext.put("foo", "bar")
  routingContext.next()

}

router.get("/some/path/B").handler() { |routingContext|
  routingContext.response().end()
}

router.get("/some/path").handler() { |routingContext|
  routingContext.reroute("/some/path/B")
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>So from the code you can see that if a request arrives at <code>/some/path</code> if first add a value to the context, then
moves to the next handler that re routes the request to <code>/some/path/B</code> which terminates the request.</p>
</div>
<div class="paragraph">
<p>You can reroute based on a new path or based on a new path and method. Note however that rerouting based on method
might introduce security issues since for example a usually safe GET request can become a DELETE.</p>
</div>
<div class="paragraph">
<p>Reroute is also allowed on the failure handler, however due to the nature of re router when called the current status
code and failure reason are reset. In order the rerouted handler should generate the correct status code if needed,
for example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">router.get("/my-pretty-notfound-handler").handler() { |ctx|
  ctx.response().set_status_code(404).end("NOT FOUND fancy html here!!!")
}

router.get().failure_handler() { |ctx|
  if (ctx.status_code() == 404)
    ctx.reroute("/my-pretty-notfound-handler")
  else
    ctx.next()
  end
}</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_sub_routers">Sub-routers</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Sometimes if you have a lot of handlers it can make sense to split them up into multiple routers. This is also useful
if you want to reuse a set of handlers in a different application, rooted at a different path root.</p>
</div>
<div class="paragraph">
<p>To do this you can mount a router at a <em>mount point</em> in another router. The router that is mounted is called a
<em>sub-router</em>. Sub routers can mount other sub routers so you can have several levels of sub-routers if you like.</p>
</div>
<div class="paragraph">
<p>Let&#8217;s look at a simple example of a sub-router mounted with another router.</p>
</div>
<div class="paragraph">
<p>This sub-router will maintain the set of handlers that corresponds to a simple fictional REST API. We will mount that on another
router. The full implementation of the REST API is not shown.</p>
</div>
<div class="paragraph">
<p>Here&#8217;s the sub-router:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx-web/router'

restAPI = VertxWeb::Router.router(vertx)

restAPI.get("/products/:productID").handler() { |rc|

  # TODO Handle the lookup of the product....
  rc.response().write(productJSON)

}

restAPI.put("/products/:productID").handler() { |rc|

  # TODO Add a new product...
  rc.response().end()

}

restAPI.delete("/products/:productID").handler() { |rc|

  # TODO delete the product...
  rc.response().end()

}</code></pre>
</div>
</div>
<div class="paragraph">
<p>If this router was used as a top level router, then GET/PUT/DELETE requests to urls like <code>/products/product1234</code>
would invoke the  API.</p>
</div>
<div class="paragraph">
<p>However, let&#8217;s say we already have a web-site as described by another router:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx-web/router'
mainRouter = VertxWeb::Router.router(vertx)

# Handle static resources
mainRouter.route("/static/*").handler(&amp;myStaticHandler)

mainRouter.route(".*\\.templ").handler(&amp;myTemplateHandler)</code></pre>
</div>
</div>
<div class="paragraph">
<p>We can now mount the sub router on the main router, against a mount point, in this case <code>/productsAPI</code></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">mainRouter.mount_sub_router("/productsAPI", restAPI)</code></pre>
</div>
</div>
<div class="paragraph">
<p>This means the REST API is now accessible via paths like: <code>/productsAPI/products/product1234</code></p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_localization">Localization</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Vert.x Web parses the <code>Accept-Language</code> header and provides some helper methods to identify which is the preferred
locale for a client or the sorted list of preferred locales by quality.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">route = router.get("/localized").handler() { |rc|
  # although it might seem strange by running a loop with a switch we
  # make sure that the locale order of preference is preserved when
  # replying in the users language.
  rc.acceptable_locales().each do |locale|
    return
  end
  # we do not know the user language so lets just inform that back:
  rc.response().end("Sorry we don't speak: #{rc.preferred_locale()}")
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The main method <code><a href="../../yardoc/VertxWeb/RoutingContext.html#acceptable_locales-instance_method">acceptableLocales</a></code> will return the ordered list of locales the
user understands, if you&#8217;re only interested in the user prefered locale then the helper:
<code><a href="../../yardoc/VertxWeb/RoutingContext.html#preferred_locale-instance_method">preferredLocale</a></code> will return the 1st element of the list or <code>null</code> if no
locale was provided by the user.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_default_404_handling">Default 404 Handling</h2>
<div class="sectionbody">
<div class="paragraph">
<p>If no routes match for any particular request, Vert.x-Web will signal a 404 error.</p>
</div>
<div class="paragraph">
<p>This can then be handled by your own error handler, or perhaps the augmented error handler that we supply to use,
or if no error handler is provided Vert.x-Web will send back a basic 404 (Not Found) response.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_error_handling">Error handling</h2>
<div class="sectionbody">
<div class="paragraph">
<p>As well as setting handlers to handle requests you can also set handlers to handle failures in routing.</p>
</div>
<div class="paragraph">
<p>Failure handlers are used with the exact same route matching criteria that you use with normal handlers.</p>
</div>
<div class="paragraph">
<p>For example you can provide a failure handler that will only handle failures on certain paths, or for certain HTTP methods.</p>
</div>
<div class="paragraph">
<p>This allows you to set different failure handlers for different parts of your application.</p>
</div>
<div class="paragraph">
<p>Here&#8217;s an example failure handler that will only be called for failure that occur when routing to GET requests
to paths that start with <code>/somepath/</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">route = router.get("/somepath/*")

route.failure_handler() { |frc|

  # This will be called for failures that occur
  # when routing requests to paths starting with
  # '/somepath/'

}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Failure routing will occur if a handler throws an exception, or if a handler calls
<code><a href="../../yardoc/VertxWeb/RoutingContext.html#fail-instance_method">fail</a></code> specifying an HTTP status code to deliberately signal a failure.</p>
</div>
<div class="paragraph">
<p>If an exception is caught from a handler this will result in a failure with status code <code>500</code> being signalled.</p>
</div>
<div class="paragraph">
<p>When handling the failure, the failure handler is passed the routing context which also allows the failure or failure code
to be retrieved so the failure handler can use that to generate a failure response.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">route1 = router.get("/somepath/path1/")

route1.handler() { |routingContext|

  # Let's say this throws a RuntimeException
  raise "something happened!"

}

route2 = router.get("/somepath/path2")

route2.handler() { |routingContext|

  # This one deliberately fails the request passing in the status code
  # E.g. 403 - Forbidden
  routingContext.fail(403)

}

# Define a failure handler
# This will get called for any failures in the above handlers
route3 = router.get("/somepath/*")

route3.failure_handler() { |failureRoutingContext|

  statusCode = failureRoutingContext.status_code()

  # Status code will be 500 for the RuntimeException or 403 for the other failure
  response = failureRoutingContext.response()
  response.set_status_code(statusCode).end("Sorry! Not today")

}</code></pre>
</div>
</div>
<div class="paragraph">
<p>For the eventuality that an error occurs when running the error handler related usage of not allowed characters in
status message header, then the original status message will be changed to the default message from the error code.
This is a tradeoff to keep the semantics of the HTTP protocol working instead of abruptly creash and close the socket
without properly completing the protocol.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_request_body_handling">Request body handling</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The <code><a href="../../yardoc/VertxWeb/BodyHandler.html">BodyHandler</a></code> allows you to retrieve request bodies, limit body sizes and handle
file uploads.</p>
</div>
<div class="paragraph">
<p>You should make sure a body handler is on a matching route for any requests that require this functionality.</p>
</div>
<div class="paragraph">
<p>The usage of this handler requires that it is installed as soon as possible in the router since it needs
to install handlers to consume the HTTP request body and this must be done before executing any async call.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx-web/body_handler'

# This body handler will be called for all routes
router.route().handler(&amp;VertxWeb::BodyHandler.create().method(:handle))</code></pre>
</div>
</div>
<div class="sect2">
<h3 id="_getting_the_request_body">Getting the request body</h3>
<div class="paragraph">
<p>If you know the request body is JSON, then you can use <code><a href="../../yardoc/VertxWeb/RoutingContext.html#get_body_as_json-instance_method">getBodyAsJson</a></code>,
if you know it&#8217;s a string you can use <code><a href="../../yardoc/VertxWeb/RoutingContext.html#get_body_as_string-instance_method">getBodyAsString</a></code>, or to
retrieve it as a buffer use <code><a href="../../yardoc/VertxWeb/RoutingContext.html#get_body-instance_method">getBody</a></code>.</p>
</div>
</div>
<div class="sect2">
<h3 id="_limiting_body_size">Limiting body size</h3>
<div class="paragraph">
<p>To limit the size of a request body, create the body handler then use <code><a href="../../yardoc/VertxWeb/BodyHandler.html#set_body_limit-instance_method">setBodyLimit</a></code>
to specifying the maximum body size, in bytes. This is useful to avoid running out of memory with very large bodies.</p>
</div>
<div class="paragraph">
<p>If an attempt to send a body greater than the maximum size is made, an HTTP status code of 413 - <code>Request Entity Too Large</code>,
will be sent.</p>
</div>
<div class="paragraph">
<p>There is no body limit by default.</p>
</div>
</div>
<div class="sect2">
<h3 id="_merging_form_attributes">Merging form attributes</h3>
<div class="paragraph">
<p>By default, the body handler will merge any form attributes into the request parameters. If you don&#8217;t want this behaviour
you can use disable it with <code><a href="../../yardoc/VertxWeb/BodyHandler.html#set_merge_form_attributes-instance_method">setMergeFormAttributes</a></code>.</p>
</div>
</div>
<div class="sect2">
<h3 id="_handling_file_uploads">Handling file uploads</h3>
<div class="paragraph">
<p>Body handler is also used to handle multi-part file uploads.</p>
</div>
<div class="paragraph">
<p>If a body handler is on a matching route for the request, any file uploads will be automatically streamed to the
uploads directory, which is <code>file-uploads</code> by default.</p>
</div>
<div class="paragraph">
<p>Each file will be given an automatically generated file name, and the file uploads will be available on the routing
context with <code><a href="../../yardoc/VertxWeb/RoutingContext.html#file_uploads-instance_method">fileUploads</a></code>.</p>
</div>
<div class="paragraph">
<p>Here&#8217;s an example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx-web/body_handler'

router.route().handler(&amp;VertxWeb::BodyHandler.create().method(:handle))

router.post("/some/path/uploads").handler() { |routingContext|

  uploads = routingContext.file_uploads()
  # Do something with uploads....

}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Each file upload is described by a <code><a href="../../yardoc/VertxWeb/FileUpload.html">FileUpload</a></code> instance, which allows various properties
such as the name, file-name and size to be accessed.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_handling_cookies">Handling cookies</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Vert.x-Web has cookies support using the <code><a href="../../yardoc/VertxWeb/CookieHandler.html">CookieHandler</a></code>.</p>
</div>
<div class="paragraph">
<p>You should make sure a cookie handler is on a matching route for any requests that require this functionality.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx-web/cookie_handler'

# This cookie handler will be called for all routes
router.route().handler(&amp;VertxWeb::CookieHandler.create().method(:handle))</code></pre>
</div>
</div>
<div class="sect2">
<h3 id="_manipulating_cookies">Manipulating cookies</h3>
<div class="paragraph">
<p>You use <code><a href="../../yardoc/VertxWeb/RoutingContext.html#get_cookie-instance_method">getCookie</a></code> to retrieve
a cookie by name, or use <code><a href="../../yardoc/VertxWeb/RoutingContext.html#cookies-instance_method">cookies</a></code> to retrieve the entire set.</p>
</div>
<div class="paragraph">
<p>To remove a cookie, use <code><a href="../../yardoc/VertxWeb/RoutingContext.html#remove_cookie-instance_method">removeCookie</a></code>.</p>
</div>
<div class="paragraph">
<p>To add a cookie use <code><a href="../../yardoc/VertxWeb/RoutingContext.html#add_cookie-instance_method">addCookie</a></code>.</p>
</div>
<div class="paragraph">
<p>The set of cookies will be written back in the response automatically when the response headers are written so the
browser can store them.</p>
</div>
<div class="paragraph">
<p>Cookies are described by instances of <code><a href="../../yardoc/VertxWeb/Cookie.html">Cookie</a></code>. This allows you to retrieve the name,
value, domain, path and other normal cookie properties.</p>
</div>
<div class="paragraph">
<p>Here&#8217;s an example of querying and adding cookies:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx-web/cookie_handler'
require 'vertx-web/cookie'

# This cookie handler will be called for all routes
router.route().handler(&amp;VertxWeb::CookieHandler.create().method(:handle))

router.route("some/path/").handler() { |routingContext|

  someCookie = routingContext.get_cookie("mycookie")
  cookieValue = someCookie.get_value()

  # Do something with cookie...

  # Add a cookie - this will get written back in the response automatically
  routingContext.add_cookie(VertxWeb::Cookie.cookie("othercookie", "somevalue"))
}</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_handling_sessions">Handling sessions</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Vert.x-Web provides out of the box support for sessions.</p>
</div>
<div class="paragraph">
<p>Sessions last between HTTP requests for the length of a browser session and give you a place where you can add
session-scope information, such as a shopping basket.</p>
</div>
<div class="paragraph">
<p>Vert.x-Web uses session cookies to identify a session. The session cookie is temporary and will be deleted by your browser
when it&#8217;s closed.</p>
</div>
<div class="paragraph">
<p>We don&#8217;t put the actual data of your session in the session cookie - the cookie simply uses an identifier to look-up
the actual session on the server. The identifier is a random UUID generated using a secure random, so it should
be effectively unguessable.</p>
</div>
<div class="paragraph">
<p>Cookies are passed across the wire in HTTP requests and responses so it&#8217;s always wise to make sure you are using
HTTPS when sessions are being used. Vert.x will warn you if you attempt to use sessions over straight HTTP.</p>
</div>
<div class="paragraph">
<p>To enable sessions in your application you must have a <code><a href="../../yardoc/VertxWeb/SessionHandler.html">SessionHandler</a></code>
on a matching route before your application logic.</p>
</div>
<div class="paragraph">
<p>The session handler handles the creation of session cookies and the lookup of the session so you don&#8217;t have to do
that yourself.</p>
</div>
<div class="sect2">
<h3 id="_session_stores">Session stores</h3>
<div class="paragraph">
<p>To create a session handler you need to have a session store instance. The session store is the object that
holds the actual sessions for your application.</p>
</div>
<div class="paragraph">
<p>Vert.x-Web comes with two session store implementations out of the box, and you can also write your own if you prefer.</p>
</div>
<div class="sect3">
<h4 id="_local_session_store">Local session store</h4>
<div class="paragraph">
<p>With this store, sessions are stored locally in memory and only available in this instance.</p>
</div>
<div class="paragraph">
<p>This store is appropriate if you have just a single Vert.x instance of you are using sticky sessions in your application
and have configured your load balancer to always route HTTP requests to the same Vert.x instance.</p>
</div>
<div class="paragraph">
<p>If you can&#8217;t ensure your requests will all terminate on the same server then don&#8217;t use this store as your
requests might end up on a server which doesn&#8217;t know about your session.</p>
</div>
<div class="paragraph">
<p>Local session stores are implemented by using a shared local map, and have a reaper which clears out expired sessions.</p>
</div>
<div class="paragraph">
<p>The reaper interval can be configured with
<code><a href="../../yardoc/VertxWeb/LocalSessionStore.html#create-class_method">LocalSessionStore.create</a></code>.</p>
</div>
<div class="paragraph">
<p>Here are some examples of creating a <code><a href="../../yardoc/VertxWeb/LocalSessionStore.html">LocalSessionStore</a></code></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx-web/local_session_store'

# Create a local session store using defaults
store1 = VertxWeb::LocalSessionStore.create(vertx)

# Create a local session store specifying the local shared map name to use
# This might be useful if you have more than one application in the same
# Vert.x instance and want to use different maps for different applications
store2 = VertxWeb::LocalSessionStore.create(vertx, "myapp3.sessionmap")

# Create a local session store specifying the local shared map name to use and
# setting the reaper interval for expired sessions to 10 seconds
store3 = VertxWeb::LocalSessionStore.create(vertx, "myapp3.sessionmap", 10000)</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_clustered_session_store">Clustered session store</h4>
<div class="paragraph">
<p>With this store, sessions are stored in a distributed map which is accessible across the Vert.x cluster.</p>
</div>
<div class="paragraph">
<p>This store is appropriate if you&#8217;re <em>not</em> using sticky sessions, i.e. your load balancer is distributing different
requests from the same browser to different servers.</p>
</div>
<div class="paragraph">
<p>Your session is accessible from any node in the cluster using this store.</p>
</div>
<div class="paragraph">
<p>To you use a clustered session store you should make sure your Vert.x instance is clustered.</p>
</div>
<div class="paragraph">
<p>Here are some examples of creating a <code><a href="../../yardoc/VertxWeb/ClusteredSessionStore.html">ClusteredSessionStore</a></code></p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx-web/clustered_session_store'
require 'vertx/vertx'

# a clustered Vert.x
Vertx::Vertx.clustered_vertx({
  'clustered' =&gt; true
}) { |res_err,res|

  vertx = res

  # Create a clustered session store using defaults
  store1 = VertxWeb::ClusteredSessionStore.create(vertx)

  # Create a clustered session store specifying the distributed map name to use
  # This might be useful if you have more than one application in the cluster
  # and want to use different maps for different applications
  store2 = VertxWeb::ClusteredSessionStore.create(vertx, "myclusteredapp3.sessionmap")
}</code></pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_creating_the_session_handler">Creating the session handler</h3>
<div class="paragraph">
<p>Once you&#8217;ve created a session store you can create a session handler, and add it to a route. You should make sure
your session handler is routed to before your application handlers.</p>
</div>
<div class="paragraph">
<p>You&#8217;ll also need to include a <code><a href="../../yardoc/VertxWeb/CookieHandler.html">CookieHandler</a></code> as the session handler uses cookies to
lookup the session. The cookie handler should be before the session handler when routing.</p>
</div>
<div class="paragraph">
<p>Here&#8217;s an example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx-web/router'
require 'vertx-web/cookie_handler'
require 'vertx-web/clustered_session_store'
require 'vertx-web/session_handler'

router = VertxWeb::Router.router(vertx)

# We need a cookie handler first
router.route().handler(&amp;VertxWeb::CookieHandler.create().method(:handle))

# Create a clustered session store using defaults
store = VertxWeb::ClusteredSessionStore.create(vertx)

sessionHandler = VertxWeb::SessionHandler.create(store)

# Make sure all requests are routed through the session handler too
router.route().handler(&amp;sessionHandler.method(:handle))

# Now your application handlers
router.route("/somepath/blah/").handler() { |routingContext|

  session = routingContext.session()
  session.put("foo", "bar")
  # etc

}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The session handler will ensure that your session is automatically looked up (or created if no session exists)
from the session store and set on the routing context before it gets to your application handlers.</p>
</div>
</div>
<div class="sect2">
<h3 id="_using_the_session">Using the session</h3>
<div class="paragraph">
<p>In your handlers you can access the session instance with <code><a href="../../yardoc/VertxWeb/RoutingContext.html#session-instance_method">session</a></code>.</p>
</div>
<div class="paragraph">
<p>You put data into the session with <code><a href="../../yardoc/VertxWeb/Session.html#put-instance_method">put</a></code>,
you get data from the session with <code><a href="../../yardoc/VertxWeb/Session.html#get-instance_method">get</a></code>, and you remove
data from the session with <code><a href="../../yardoc/VertxWeb/Session.html#remove-instance_method">remove</a></code>.</p>
</div>
<div class="paragraph">
<p>The keys for items in the session are always strings. The values can be any type for a local session store, and for
a clustered session store they can be any basic type, or <code><a href="../../yardoc/Vertx/Buffer.html">Buffer</a></code>, <code><a href="unavailable">JsonObject</a></code>,
<code><a href="unavailable">JsonArray</a></code> or a serializable object, as the values have to serialized across the cluster.</p>
</div>
<div class="paragraph">
<p>Here&#8217;s an example of manipulating session data:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx-web/cookie_handler'

router.route().handler(&amp;VertxWeb::CookieHandler.create().method(:handle))
router.route().handler(&amp;sessionHandler.method(:handle))

# Now your application handlers
router.route("/somepath/blah").handler() { |routingContext|

  session = routingContext.session()

  # Put some data from the session
  session.put("foo", "bar")

  # Retrieve some data from a session
  age = session.get("age")

  # Remove some data from a session
  obj = session.remove("myobj")

}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Sessions are automatically written back to the store after after responses are complete.</p>
</div>
<div class="paragraph">
<p>You can manually destroy a session using <code><a href="../../yardoc/VertxWeb/Session.html#destroy-instance_method">destroy</a></code>. This will remove the session
from the context and the session store. Note that if there is no session a new one will be automatically created
for the next request from the browser that&#8217;s routed through the session handler.</p>
</div>
</div>
<div class="sect2">
<h3 id="_session_timeout">Session timeout</h3>
<div class="paragraph">
<p>Sessions will be automatically timed out if they are not accessed for a time greater than the timeout period. When
a session is timed out, it is removed from the store.</p>
</div>
<div class="paragraph">
<p>Sessions are automatically marked as accessed when a request arrives and the session is looked up and and when the
response is complete and the session is stored back in the store.</p>
</div>
<div class="paragraph">
<p>You can also use <code><a href="../../yardoc/VertxWeb/Session.html#set_accessed-instance_method">setAccessed</a></code> to manually mark a session as accessed.</p>
</div>
<div class="paragraph">
<p>The session timeout can be configured when creating the session handler. Default timeout is 30 minutes.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_authentication_authorisation">Authentication / authorisation</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Vert.x comes with some out-of-the-box handlers for handling both authentication and authorisation.</p>
</div>
<div class="sect2">
<h3 id="_creating_an_auth_handler">Creating an auth handler</h3>
<div class="paragraph">
<p>To create an auth handler you need an instance of <code><a href="../../yardoc/VertxAuthCommon/AuthProvider.html">AuthProvider</a></code>. Auth provider is
used for authentication and authorisation of users. Vert.x provides several auth provider instances out of the box
in the vertx-auth project. For full information on auth providers and how to use and configure them
please consult the auth documentation.</p>
</div>
<div class="paragraph">
<p>Here&#8217;s a simple example of creating a basic auth handler given an auth provider.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx-web/cookie_handler'
require 'vertx-web/local_session_store'
require 'vertx-web/session_handler'
require 'vertx-web/basic_auth_handler'

router.route().handler(&amp;VertxWeb::CookieHandler.create().method(:handle))
router.route().handler(&amp;VertxWeb::SessionHandler.create(VertxWeb::LocalSessionStore.create(vertx)).method(:handle))

basicAuthHandler = VertxWeb::BasicAuthHandler.create(authProvider)</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_handling_auth_in_your_application">Handling auth in your application</h3>
<div class="paragraph">
<p>Let&#8217;s say you want all requests to paths that start with <code>/private/</code> to be subject to auth. To do that you make sure
your auth handler is before your application handlers on those paths:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx-web/cookie_handler'
require 'vertx-web/local_session_store'
require 'vertx-web/session_handler'
require 'vertx-web/user_session_handler'
require 'vertx-web/basic_auth_handler'

router.route().handler(&amp;VertxWeb::CookieHandler.create().method(:handle))
router.route().handler(&amp;VertxWeb::SessionHandler.create(VertxWeb::LocalSessionStore.create(vertx)).method(:handle))
router.route().handler(&amp;VertxWeb::UserSessionHandler.create(authProvider).method(:handle))

basicAuthHandler = VertxWeb::BasicAuthHandler.create(authProvider)

# All requests to paths starting with '/private/' will be protected
router.route("/private/*").handler(&amp;basicAuthHandler.method(:handle))

router.route("/someotherpath").handler() { |routingContext|

  # This will be public access - no login required

}

router.route("/private/somepath").handler() { |routingContext|

  # This will require a login

  # This will have the value true
  isAuthenticated = routingContext.user() != nil

}</code></pre>
</div>
</div>
<div class="paragraph">
<p>If the auth handler has successfully authenticated and authorised the user it will inject a <code><a href="../../yardoc/VertxAuthCommon/User.html">User</a></code>
object into the <code><a href="../../yardoc/VertxWeb/RoutingContext.html">RoutingContext</a></code> so it&#8217;s available in your handlers with:
<code><a href="../../yardoc/VertxWeb/RoutingContext.html#user-instance_method">user</a></code>.</p>
</div>
<div class="paragraph">
<p>If you want your User object to be stored in the session so it&#8217;s available between requests so you don&#8217;t have to
authenticate on each request, then you should make sure you have a session handler and a user session handler on matching
routes before the auth handler.</p>
</div>
<div class="paragraph">
<p>Once you have your user object you can also programmatically use the methods on it to authorise the user.</p>
</div>
<div class="paragraph">
<p>If you want to cause the user to be logged out you can call <code><a href="../../yardoc/VertxWeb/RoutingContext.html#clear_user-instance_method">clearUser</a></code>
on the routing context.</p>
</div>
</div>
<div class="sect2">
<h3 id="_http_basic_authentication">HTTP Basic Authentication</h3>
<div class="paragraph">
<p><a href="http://en.wikipedia.org/wiki/Basic_access_authentication">HTTP Basic Authentication</a> is a simple means of authentication
that can be appropriate for simple applications.</p>
</div>
<div class="paragraph">
<p>With basic auth, credentials are sent unencrypted across the wire in HTTP headers so it&#8217;s essential that you serve
your application using HTTPS not HTTP.</p>
</div>
<div class="paragraph">
<p>With basic auth, if a user requests a resource that requires authorisation, the basic auth handler will send back
a <code>401</code> response with the header <code>WWW-Authenticate</code> set. This prompts the browser to show a log-in dialogue and
prompt the user to enter their username and password.</p>
</div>
<div class="paragraph">
<p>The request is made to the resource again, this time with the <code>Authorization</code> header set, containing the username
and password encoded in Base64.</p>
</div>
<div class="paragraph">
<p>When the basic auth handler receives this information, it calls the configured <code><a href="../../yardoc/VertxAuthCommon/AuthProvider.html">AuthProvider</a></code>
with the username and password to authenticate the user. If the authentication is successful the handler attempts
to authorise the user. If that is successful then the routing of the request is allowed to continue to the application
handlers, otherwise a <code>403</code> response is returned to signify that access is denied.</p>
</div>
<div class="paragraph">
<p>The auth handler can be set-up with a set of authorities that are required for access to the resources to
be granted.</p>
</div>
</div>
<div class="sect2">
<h3 id="_redirect_auth_handler">Redirect auth handler</h3>
<div class="paragraph">
<p>With redirect auth handling the user is redirected to towards a login page in the case they are trying to access
a protected resource and they are not logged in.</p>
</div>
<div class="paragraph">
<p>The user then fills in the login form and submits it. This is handled by the server which authenticates
the user and, if authenticated redirects the user back to the original resource.</p>
</div>
<div class="paragraph">
<p>To use redirect auth you configure an instance of <code><a href="../../yardoc/VertxWeb/RedirectAuthHandler.html">RedirectAuthHandler</a></code> instead of a
basic auth handler.</p>
</div>
<div class="paragraph">
<p>You will also need to setup handlers to serve your actual login page, and a handler to handle the actual login itself.
To handle the login we provide a prebuilt handler <code><a href="../../yardoc/VertxWeb/FormLoginHandler.html">FormLoginHandler</a></code> for the purpose.</p>
</div>
<div class="paragraph">
<p>Here&#8217;s an example of a simple app, using a redirect auth handler on the default redirect url <code>/loginpage</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx-web/cookie_handler'
require 'vertx-web/local_session_store'
require 'vertx-web/session_handler'
require 'vertx-web/user_session_handler'
require 'vertx-web/redirect_auth_handler'
require 'vertx-web/form_login_handler'
require 'vertx-web/static_handler'

router.route().handler(&amp;VertxWeb::CookieHandler.create().method(:handle))
router.route().handler(&amp;VertxWeb::SessionHandler.create(VertxWeb::LocalSessionStore.create(vertx)).method(:handle))
router.route().handler(&amp;VertxWeb::UserSessionHandler.create(authProvider).method(:handle))

redirectAuthHandler = VertxWeb::RedirectAuthHandler.create(authProvider)

# All requests to paths starting with '/private/' will be protected
router.route("/private/*").handler(&amp;redirectAuthHandler.method(:handle))

# Handle the actual login
router.route("/login").handler(&amp;VertxWeb::FormLoginHandler.create(authProvider).method(:handle))

# Set a static server to serve static resources, e.g. the login page
router.route().handler(&amp;VertxWeb::StaticHandler.create().method(:handle))

router.route("/someotherpath").handler() { |routingContext|
  # This will be public access - no login required
}

router.route("/private/somepath").handler() { |routingContext|

  # This will require a login

  # This will have the value true
  isAuthenticated = routingContext.user() != nil

}</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_jwt_authorisation">JWT authorisation</h3>
<div class="paragraph">
<p>With JWT authorisation resources can be protected by means of permissions and users without enough rights are denied
access.</p>
</div>
<div class="paragraph">
<p>To use this handler there are 2 steps involved:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Setup an handler to issue tokens (or rely on a 3rd party)</p>
</li>
<li>
<p>Setup the handler to filter the requests</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Please note that these 2 handlers should be only available on HTTPS, not doing so allows sniffing the tokens in
transit which leads to session hijacking attacks.</p>
</div>
<div class="paragraph">
<p>Here&#8217;s an example on how to issue tokens:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx-web/router'
require 'vertx-auth-jwt/jwt_auth'

router = VertxWeb::Router.router(vertx)

authConfig = {
  'keyStore' =&gt; {
    'type' =&gt; "jceks",
    'path' =&gt; "keystore.jceks",
    'password' =&gt; "secret"
  }
}

authProvider = VertxAuthJwt::JWTAuth.create(vertx, authConfig)

router.route("/login").handler() { |ctx|
  # this is an example, authentication should be done with another provider...
  if ("paulo".==(ctx.request().get_param("username")) &amp;&amp; "secret".==(ctx.request().get_param("password")))
    ctx.response().end(authProvider.generate_token({
      'sub' =&gt; "paulo"
    }, {
    }))
  else
    ctx.fail(401)
  end
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Now that your client has a token all it is required is that for <strong>all</strong> consequent request the HTTP header
<code>Authorization</code> is filled with: <code>Bearer &lt;token&gt;</code> e.g.:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx-web/router'
require 'vertx-auth-jwt/jwt_auth'
require 'vertx-web/jwt_auth_handler'

router = VertxWeb::Router.router(vertx)

authConfig = {
  'keyStore' =&gt; {
    'type' =&gt; "jceks",
    'path' =&gt; "keystore.jceks",
    'password' =&gt; "secret"
  }
}

authProvider = VertxAuthJwt::JWTAuth.create(vertx, authConfig)

router.route("/protected/*").handler(&amp;VertxWeb::JWTAuthHandler.create(authProvider).method(:handle))

router.route("/protected/somepage").handler() { |ctx|
  # some handle code...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>JWT allows you to add any information you like to the token itself. By doing this there is no state in the server
which allows you to scale your applications without need for clustered session data. In order to add data to the
token, during the creation of the token just add data to the JsonObject parameter:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx-auth-jwt/jwt_auth'

authConfig = {
  'keyStore' =&gt; {
    'type' =&gt; "jceks",
    'path' =&gt; "keystore.jceks",
    'password' =&gt; "secret"
  }
}

authProvider = VertxAuthJwt::JWTAuth.create(vertx, authConfig)

authProvider.generate_token({
  'sub' =&gt; "paulo",
  'someKey' =&gt; "some value"
}, {
})</code></pre>
</div>
</div>
<div class="paragraph">
<p>And the same when consuming:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">handler = lambda { |rc|
  theSubject = rc.user().principal()['sub']
  someKey = rc.user().principal()['someKey']
}</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_configuring_required_authorities">Configuring required authorities</h3>
<div class="paragraph">
<p>With any auth handler you can also configure required authorities to access the resource.</p>
</div>
<div class="paragraph">
<p>By default, if no authorities are configured then it is sufficient to be logged in to access the resource, otherwise
the user must be both logged in (authenticated) and have the required authorities.</p>
</div>
<div class="paragraph">
<p>Here&#8217;s an example of configuring an app so that different authorities are required for different parts of the
app. Note that the meaning of the authorities is determined by the underlying auth provider that you use. E.g. some
may support a role/permission based model but others might use another model.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx-web/redirect_auth_handler'

listProductsAuthHandler = VertxWeb::RedirectAuthHandler.create(authProvider)
listProductsAuthHandler.add_authority("list_products")

# Need "list_products" authority to list products
router.route("/listproducts/*").handler(&amp;listProductsAuthHandler.method(:handle))

settingsAuthHandler = VertxWeb::RedirectAuthHandler.create(authProvider)
settingsAuthHandler.add_authority("role:admin")

# Only "admin" has access to /private/settings
router.route("/private/settings/*").handler(&amp;settingsAuthHandler.method(:handle))</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_serving_static_resources">Serving static resources</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Vert.x-Web comes with an out of the box handler for serving static web resources so you can write static web servers
very easily.</p>
</div>
<div class="paragraph">
<p>To serve static resources such as <code>.html</code>, <code>.css</code>, <code>.js</code> or any other static resource, you use an instance of
<code><a href="../../yardoc/VertxWeb/StaticHandler.html">StaticHandler</a></code>.</p>
</div>
<div class="paragraph">
<p>Any requests to paths handled by the static handler will result in files being served from a directory on the file system
or from the classpath. The default static file directory is <code>webroot</code> but this can be configured.</p>
</div>
<div class="paragraph">
<p>In the following example all requests to paths starting with <code>/static/</code> will get served from the directory <code>webroot</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx-web/static_handler'

router.route("/static/*").handler(&amp;VertxWeb::StaticHandler.create().method(:handle))</code></pre>
</div>
</div>
<div class="paragraph">
<p>For example, if there was a request with path <code>/static/css/mystyles.css</code> the static serve will look for a file in the
directory <code>webroot/static/css/mystyle.css</code>.</p>
</div>
<div class="paragraph">
<p>It will also look for a file on the classpath called <code>webroot/static/css/mystyle.css</code>. This means you can package up all your
static resources into a jar file (or fatjar) and distribute them like that.</p>
</div>
<div class="paragraph">
<p>When Vert.x finds a resource on the classpath for the first time it extracts it and caches it in a temporary directory
on disk so it doesn&#8217;t have to do this each time.</p>
</div>
<div class="paragraph">
<p>The handler will handle range aware requests. When a client makes a request to a static resource, the handler will
notify that it can handle range aware request by stating the unit on the <code>Accept-Ranges</code> header. Further requests
that contain the <code>Range</code> header with the correct unit and start and end indexes will then receive partial responses
with the correct <code>Content-Range</code> header.</p>
</div>
<div class="sect2">
<h3 id="_configuring_caching">Configuring caching</h3>
<div class="paragraph">
<p>By default the static handler will set cache headers to enable browsers to effectively cache files.</p>
</div>
<div class="paragraph">
<p>Vert.x-Web sets the headers <code>cache-control</code>,<code>last-modified</code>, and <code>date</code>.</p>
</div>
<div class="paragraph">
<p><code>cache-control</code> is set to <code>max-age=86400</code> by default. This corresponds to one day. This can be configured with
<code><a href="../../yardoc/VertxWeb/StaticHandler.html#set_max_age_seconds-instance_method">setMaxAgeSeconds</a></code> if required.</p>
</div>
<div class="paragraph">
<p>If a browser sends a GET or a HEAD request with an <code>if-modified-since</code> header and the resource has not been modified
since that date, a <code>304</code> status is returned which tells the browser to use its locally cached resource.</p>
</div>
<div class="paragraph">
<p>If handling of cache headers is not required, it can be disabled with <code><a href="../../yardoc/VertxWeb/StaticHandler.html#set_caching_enabled-instance_method">setCachingEnabled</a></code>.</p>
</div>
<div class="paragraph">
<p>When cache handling is enabled Vert.x-Web will cache the last modified date of resources in memory, this avoids a disk hit
to check the actual last modified date every time.</p>
</div>
<div class="paragraph">
<p>Entries in the cache have an expiry time, and after that time, the file on disk will be checked again and the cache
entry updated.</p>
</div>
<div class="paragraph">
<p>If you know that your files never change on disk, then the cache entry will effectively never expire. This is the
default.</p>
</div>
<div class="paragraph">
<p>If you know that your files might change on disk when the server is running then you can set files read only to false with
<code><a href="../../yardoc/VertxWeb/StaticHandler.html#set_files_read_only-instance_method">setFilesReadOnly</a></code>.</p>
</div>
<div class="paragraph">
<p>To enable the maximum number of entries that can be cached in memory at any one time you can use
<code><a href="../../yardoc/VertxWeb/StaticHandler.html#set_max_cache_size-instance_method">setMaxCacheSize</a></code>.</p>
</div>
<div class="paragraph">
<p>To configure the expiry time of cache entries you can use <code><a href="../../yardoc/VertxWeb/StaticHandler.html#set_cache_entry_timeout-instance_method">setCacheEntryTimeout</a></code>.</p>
</div>
</div>
<div class="sect2">
<h3 id="_configuring_the_index_page">Configuring the index page</h3>
<div class="paragraph">
<p>Any requests to the root path <code>/</code> will cause the index page to be served. By default the index page is <code>index.html</code>.
This can be configured with <code><a href="../../yardoc/VertxWeb/StaticHandler.html#set_index_page-instance_method">setIndexPage</a></code>.</p>
</div>
</div>
<div class="sect2">
<h3 id="_changing_the_web_root">Changing the web root</h3>
<div class="paragraph">
<p>By default static resources will be served from the directory <code>webroot</code>. To configure this use
<code><a href="../../yardoc/VertxWeb/StaticHandler.html#set_web_root-instance_method">setWebRoot</a></code>.</p>
</div>
</div>
<div class="sect2">
<h3 id="_serving_hidden_files">Serving hidden files</h3>
<div class="paragraph">
<p>By default the serve will serve hidden files (files starting with <code>.</code>).</p>
</div>
<div class="paragraph">
<p>If you do not want hidden files to be served you can configure it with <code><a href="../../yardoc/VertxWeb/StaticHandler.html#set_include_hidden-instance_method">setIncludeHidden</a></code>.</p>
</div>
</div>
<div class="sect2">
<h3 id="_directory_listing">Directory listing</h3>
<div class="paragraph">
<p>The server can also perform directory listing. By default directory listing is disabled. To enabled it use
<code><a href="../../yardoc/VertxWeb/StaticHandler.html#set_directory_listing-instance_method">setDirectoryListing</a></code>.</p>
</div>
<div class="paragraph">
<p>When directory listing is enabled the content returned depends on the content type in the <code>accept</code> header.</p>
</div>
<div class="paragraph">
<p>For <code>text/html</code> directory listing, the template used to render the directory listing page can be configured with
<code><a href="../../yardoc/VertxWeb/StaticHandler.html#set_directory_template-instance_method">setDirectoryTemplate</a></code>.</p>
</div>
</div>
<div class="sect2">
<h3 id="_disabling_file_caching_on_disk">Disabling file caching on disk</h3>
<div class="paragraph">
<p>By default, Vert.x will cache files that are served from the classpath into a file on disk in a sub-directory of a
directory called <code>.vertx</code> in the current working directory. This is mainly useful when deploying services as
fatjars in production where serving a file from the classpath every time can be slow.</p>
</div>
<div class="paragraph">
<p>In development this can cause a problem, as if you update your static content while the server is running, the
cached file will be served not the updated file.</p>
</div>
<div class="paragraph">
<p>To disable file caching you can provide the system property <code>vertx.disableFileCaching</code> with the value <code>true</code>. E.g. you
could set up a run configuration in your IDE to set this when runnning your main class.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_cors_handling">CORS handling</h2>
<div class="sectionbody">
<div class="paragraph">
<p><a href="http://en.wikipedia.org/wiki/Cross-origin_resource_sharing">Cross Origin Resource Sharing</a> is a safe mechanism for
allowing resources to be requested from one domain and served from another.</p>
</div>
<div class="paragraph">
<p>Vert.x-Web includes a handler <code><a href="../../yardoc/VertxWeb/CorsHandler.html">CorsHandler</a></code> that handles the CORS protocol for you.</p>
</div>
<div class="paragraph">
<p>Here&#8217;s an example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx-web/cors_handler'

# Will only accept GET requests from origin "vertx.io"
router.route().handler(&amp;VertxWeb::CorsHandler.create("vertx\\.io").allowed_method(:GET).method(:handle))

router.route().handler() { |routingContext|

  # Your app handlers

}</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_templates">Templates</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Vert.x-Web includes dynamic page generation capabilities by including out of the box support for several popular template
engines. You can also easily add your own.</p>
</div>
<div class="paragraph">
<p>Template engines are described by <code><a href="../../yardoc/VertxWeb/TemplateEngine.html">TemplateEngine</a></code>. In order to render a template
<code><a href="../../yardoc/VertxWeb/TemplateEngine.html#render-instance_method">render</a></code> is used.</p>
</div>
<div class="paragraph">
<p>The simplest way to use templates is not to call the template engine directly but to use the
<code><a href="../../yardoc/VertxWeb/TemplateHandler.html">TemplateHandler</a></code>.
This handler calls the template engine for you based on the path in the HTTP request.</p>
</div>
<div class="paragraph">
<p>By default the template handler will look for templates in a directory called <code>templates</code>. This can be configured.</p>
</div>
<div class="paragraph">
<p>The handler will return the results of rendering with a content type of <code>text/html</code> by default. This can also be configured.</p>
</div>
<div class="paragraph">
<p>When you create the template handler you pass in an instance of the template engine you want. Template engines are
not embedded in vertx-web so, you need to configure your project to access them. Configuration is provided for
each template engine.</p>
</div>
<div class="paragraph">
<p>Here are some examples:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx-web/handlebars_template_engine'
require 'vertx-web/template_handler'

engine = VertxWeb::HandlebarsTemplateEngine.create()
handler = VertxWeb::TemplateHandler.create(engine)

# This will route all GET requests starting with /dynamic/ to the template handler
# E.g. /dynamic/graph.hbs will look for a template in /templates/dynamic/graph.hbs
router.get("/dynamic/*").handler(&amp;handler.method(:handle))

# Route all GET requests for resource ending in .hbs to the template handler
router.get_with_regex(".+\\.hbs").handler(&amp;handler.method(:handle))</code></pre>
</div>
</div>
<div class="sect2">
<h3 id="_mvel_template_engine">MVEL template engine</h3>
<div class="paragraph">
<p>To use MVEL, you need to add the following <em>dependency</em> to your project:
<code>io.vertx:vertx-web-templ-mvel:3.3.3</code>. Create an instance of the MVEL template engine using:
<code>io.vertx.ext.web.templ.MVELTemplateEngine#create()</code></p>
</div>
<div class="paragraph">
<p>When using the MVEL template engine, it will by default look for
templates with the <code>.templ</code> extension if no extension is specified in the file name.</p>
</div>
<div class="paragraph">
<p>The routing context <code><a href="../../yardoc/VertxWeb/RoutingContext.html">RoutingContext</a></code> is available
in the MVEL template as the <code>context</code> variable, this means you can render the template based on anything in the context
including the request, response, session or context data.</p>
</div>
<div class="paragraph">
<p>Here are some examples:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>The request path is @{context.request().path()}

The variable 'foo' from the session is @{context.session().get('foo')}

The value 'bar' from the context data is @{context.get('bar')}</pre>
</div>
</div>
<div class="paragraph">
<p>Please consult the <a href="http://mvel.codehaus.org/MVEL+2.0+Templating+Guide">MVEL templates documentation</a> for how to write
MVEL templates.</p>
</div>
</div>
<div class="sect2">
<h3 id="_jade_template_engine">Jade template engine</h3>
<div class="paragraph">
<p>To use the Jade template engine, you need to add the following <em>dependency</em> to your project:
<code>io.vertx:vertx-web-templ-jade:3.3.3</code>. Create an instance of the Jade template engine using:
<code>io.vertx.ext.web.templ.JadeTemplateEngine#create()</code>.</p>
</div>
<div class="paragraph">
<p>When using the Jade template engine, it will by default look for
templates with the <code>.jade</code> extension if no extension is specified in the file name.</p>
</div>
<div class="paragraph">
<p>The routing context <code><a href="../../yardoc/VertxWeb/RoutingContext.html">RoutingContext</a></code> is available
in the Jade template as the <code>context</code> variable, this means you can render the template based on anything in the context
including the request, response, session or context data.</p>
</div>
<div class="paragraph">
<p>Here are some examples:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>!!! 5
html
  head
    title= context.get('foo') + context.request().path()
  body</pre>
</div>
</div>
<div class="paragraph">
<p>Please consult the <a href="https://github.com/neuland/jade4j">Jade4j documentation</a> for how to write
Jade templates.</p>
</div>
</div>
<div class="sect2">
<h3 id="_handlebars_template_engine">Handlebars template engine</h3>
<div class="paragraph">
<p>To use Handlebars, you need to add the following <em>dependency</em> to your project:
<code>io.vertx:vertx-web-templ-handlebars:3.3.3</code>. Create an instance of the Handlebars template engine
using: <code>io.vertx.ext.web.templ.HandlebarsTemplateEngine#create()</code>.</p>
</div>
<div class="paragraph">
<p>When using the Handlebars template engine, it will by default look for
templates with the <code>.hbs</code> extension if no extension is specified in the file name.</p>
</div>
<div class="paragraph">
<p>Handlebars templates are not able to call arbitrary methods in objects so we can&#8217;t just pass the routing context
into the template and let the template introspect it like we can with other template engines.</p>
</div>
<div class="paragraph">
<p>Instead, the context <code><a href="../../yardoc/VertxWeb/RoutingContext.html#data-instance_method">data</a></code> is available in the template.</p>
</div>
<div class="paragraph">
<p>If you want to have access to other data like the request path, request params or session data you should
add it the context data in a handler before the template handler. For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx-web/template_handler'

handler = VertxWeb::TemplateHandler.create(engine)

router.get("/dynamic").handler() { |routingContext|

  routingContext.put("request_path", routingContext.request().path())
  routingContext.put("session_data", routingContext.session().data())

  routingContext.next()
}

router.get("/dynamic/").handler(&amp;handler.method(:handle))</code></pre>
</div>
</div>
<div class="paragraph">
<p>Please consult the <a href="https://github.com/jknack/handlebars.java">Handlebars Java port documentation</a> for how to write
handlebars templates.</p>
</div>
</div>
<div class="sect2">
<h3 id="_thymeleaf_template_engine">Thymeleaf template engine</h3>
<div class="paragraph">
<p>To use Thymeleaf, you need to add the following <em>dependency</em> to your project:
<code>io.vertx:vertx-web-templ-thymeleaf:3.3.3</code>. Create an instance of the Thymeleaf template engine
using: <code>io.vertx.ext.web.templ.ThymeleafTemplateEngine#create()</code>.</p>
</div>
<div class="paragraph">
<p>When using the Thymeleaf template engine, it will by default look for
templates with the <code>.html</code> extension if no extension is specified in the file name.</p>
</div>
<div class="paragraph">
<p>The routing context <code><a href="../../yardoc/VertxWeb/RoutingContext.html">RoutingContext</a></code> is available
in the Thymeleaf template as the <code>context</code> variable, this means you can render the template based on anything in the context
including the request, response, session or context data.</p>
</div>
<div class="paragraph">
<p>Here are some examples:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>[snip]
&lt;p th:text="${context.get('foo')}"&gt;&lt;/p&gt;
&lt;p th:text="${context.get('bar')}"&gt;&lt;/p&gt;
&lt;p th:text="${context.normalisedPath()}"&gt;&lt;/p&gt;
&lt;p th:text="${context.request().params().get('param1')}"&gt;&lt;/p&gt;
&lt;p th:text="${context.request().params().get('param2')}"&gt;&lt;/p&gt;
[snip]</pre>
</div>
</div>
<div class="paragraph">
<p>Please consult the <a href="http://www.thymeleaf.org/">Thymeleaf documentation</a> for how to write
Thymeleaf templates.</p>
</div>
</div>
<div class="sect2">
<h3 id="_apache_freemarker_template_engine">Apache FreeMarker template engine</h3>
<div class="paragraph">
<p>To use Apache FreeMarker, you need to add the following <em>dependency</em> to your project:
<code>io.vertx:vertx-web-templ-freemarker:3.3.3</code>. Create an instance of the Apache FreeMarker template engine
using: <code>io.vertx.ext.web.templ.FreeMarkerTemplateEngine#create()</code>.</p>
</div>
<div class="paragraph">
<p>When using the Apache FreeMarker template engine, it will by default look for
templates with the <code>.ftl</code> extension if no extension is specified in the file name.</p>
</div>
<div class="paragraph">
<p>The routing context <code><a href="../../yardoc/VertxWeb/RoutingContext.html">RoutingContext</a></code> is available
in the Apache FreeMarker template as the <code>context</code> variable, this means you can render the template based on anything in the context
including the request, response, session or context data.</p>
</div>
<div class="paragraph">
<p>Here are some examples:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>[snip]
&lt;p th:text="${context.foo}"&gt;&lt;/p&gt;
&lt;p th:text="${context.bar}"&gt;&lt;/p&gt;
&lt;p th:text="${context.normalisedPath()}"&gt;&lt;/p&gt;
&lt;p th:text="${context.request().params().param1}"&gt;&lt;/p&gt;
&lt;p th:text="${context.request().params().param2}"&gt;&lt;/p&gt;
[snip]</pre>
</div>
</div>
<div class="paragraph">
<p>Please consult the <a href="http://www.freemarker.org/">Apache FreeMarker documentation</a> for how to write
Apache FreeMarker templates.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_error_handler">Error handler</h2>
<div class="sectionbody">
<div class="paragraph">
<p>You can render your own errors using a template handler or otherwise but Vert.x-Web also includes an out of the boxy
"pretty" error handler that can render error pages for you.</p>
</div>
<div class="paragraph">
<p>The handler is <code><a href="../../yardoc/VertxWeb/ErrorHandler.html">ErrorHandler</a></code>. To use the error handler just set it as a
failure handler for any paths that you want covered.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_request_logger">Request logger</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Vert.x-Web includes a handler <code><a href="../../yardoc/VertxWeb/LoggerHandler.html">LoggerHandler</a></code> that you can use to log HTTP requests.</p>
</div>
<div class="paragraph">
<p>By default requests are logged to the Vert.x logger which can be configured to use JUL logging, log4j or SLF4J.</p>
</div>
<div class="paragraph">
<p>See <code><a href="../enums.html#LoggerFormat">LoggerFormat</a></code>.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_serving_favicons">Serving favicons</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Vert.x-Web includes the handler <code><a href="../../yardoc/VertxWeb/FaviconHandler.html">FaviconHandler</a></code> especially for serving favicons.</p>
</div>
<div class="paragraph">
<p>Favicons can be specified using a path to the filesystem, or by default Vert.x-Web will look for a file on the classpath
with the name <code>favicon.ico</code>. This means you bundle the favicon in the jar of your application.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_timeout_handler">Timeout handler</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Vert.x-Web includes a timeout handler that you can use to timeout requests if they take too long to process.</p>
</div>
<div class="paragraph">
<p>This is configured using an instance of <code><a href="../../yardoc/VertxWeb/TimeoutHandler.html">TimeoutHandler</a></code>.</p>
</div>
<div class="paragraph">
<p>If a request times out before the response is written a <code>503</code> response will be returned to the client.</p>
</div>
<div class="paragraph">
<p>Here&#8217;s an example of using a timeout handler which will timeout all requests to paths starting with <code>/foo</code> after 5
seconds:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx-web/timeout_handler'

router.route("/foo/").handler(&amp;VertxWeb::TimeoutHandler.create(5000).method(:handle))</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_response_time_handler">Response time handler</h2>
<div class="sectionbody">
<div class="paragraph">
<p>This handler sets the header <code>x-response-time</code> response header containing the time from when the request was received
to when the response headers were written, in ms., e.g.:</p>
</div>
<div class="literalblock">
<div class="content">
<pre>x-response-time: 1456ms</pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_sockjs">SockJS</h2>
<div class="sectionbody">
<div class="paragraph">
<p>SockJS is a client side JavaScript library and protocol which provides a simple WebSocket-like interface allowing you
to make connections to SockJS servers irrespective of whether the actual browser or network will allow real WebSockets.</p>
</div>
<div class="paragraph">
<p>It does this by supporting various different transports between browser and server, and choosing one at run-time
according to browser and network capabilities.</p>
</div>
<div class="paragraph">
<p>All this is transparent to you - you are simply presented with the WebSocket-like interface which <em>just works</em>.</p>
</div>
<div class="paragraph">
<p>Please see the <a href="https://github.com/sockjs/sockjs-client">SockJS website</a> for more information on SockJS.</p>
</div>
<div class="sect2">
<h3 id="_sockjs_handler">SockJS handler</h3>
<div class="paragraph">
<p>Vert.x provides an out of the box handler called <code><a href="../../yardoc/VertxWeb/SockJSHandler.html">SockJSHandler</a></code> for
using SockJS in your Vert.x-Web applications.</p>
</div>
<div class="paragraph">
<p>You should create one handler per SockJS application using <code><a href="../../yardoc/VertxWeb/SockJSHandler.html#create-class_method">SockJSHandler.create</a></code>.
You can also specify configuration options when creating the instance. The configuration options are described with
an instance of <code><a href="../dataobjects.html#SockJSHandlerOptions">SockJSHandlerOptions</a></code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx-web/router'
require 'vertx-web/sock_js_handler'

router = VertxWeb::Router.router(vertx)

options = {
  'heartbeatInterval' =&gt; 2000
}

sockJSHandler = VertxWeb::SockJSHandler.create(vertx, options)

router.route("/myapp/*").handler(&amp;sockJSHandler.method(:handle))</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_handling_sockjs_sockets">Handling SockJS sockets</h3>
<div class="paragraph">
<p>On the server-side you set a handler on the SockJS handler, and
this will be called every time a SockJS connection is made from a client:</p>
</div>
<div class="paragraph">
<p>The object passed into the handler is a <code><a href="../../yardoc/VertxWeb/SockJSSocket.html">SockJSSocket</a></code>. This has a familiar
socket-like interface which you can read and write to similarly to a <code><a href="../../yardoc/Vertx/NetSocket.html">NetSocket</a></code> or
a <code><a href="../../yardoc/Vertx/WebSocket.html">WebSocket</a></code>. It also implements <code><a href="../../yardoc/Vertx/ReadStream.html">ReadStream</a></code> and
<code><a href="../../yardoc/Vertx/WriteStream.html">WriteStream</a></code> so you can pump it to and from other read and write streams.</p>
</div>
<div class="paragraph">
<p>Here&#8217;s an example of a simple SockJS handler that simply echoes back any back any data that it reads:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx-web/router'
require 'vertx-web/sock_js_handler'

router = VertxWeb::Router.router(vertx)

options = {
  'heartbeatInterval' =&gt; 2000
}

sockJSHandler = VertxWeb::SockJSHandler.create(vertx, options)

sockJSHandler.socket_handler() { |sockJSSocket|

  # Just echo the data back
  sockJSSocket.handler(&amp;sockJSSocket.method(:write))
}

router.route("/myapp/*").handler(&amp;sockJSHandler.method(:handle))</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_the_client_side">The client side</h3>
<div class="paragraph">
<p>In client side JavaScript you use the SockJS client side library to make connections.</p>
</div>
<div class="paragraph">
<p>You can find that <a href="http://cdn.jsdelivr.net/sockjs/0.3.4/sockjs.min.js">here</a>.</p>
</div>
<div class="paragraph">
<p>Full details for using the SockJS JavaScript client are on the <a href="https://github.com/sockjs/sockjs-client">SockJS website</a>,
but in summary you use it something like this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>var sock = new SockJS('http://mydomain.com/myapp');

sock.onopen = function() {
  console.log('open');
};

sock.onmessage = function(e) {
  console.log('message', e.data);
};

sock.onclose = function() {
  console.log('close');
};

sock.send('test');

sock.close();</pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_configuring_the_sockjs_handler">Configuring the SockJS handler</h3>
<div class="paragraph">
<p>The handler can be configured with various options using <code><a href="../dataobjects.html#SockJSHandlerOptions">SockJSHandlerOptions</a></code>.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1"><code>insertJSESSIONID</code></dt>
<dd>
<p>Insert a JSESSIONID cookie so load-balancers ensure requests for a specific SockJS session
are always routed to the correct server. Default is <code>true</code>.</p>
</dd>
<dt class="hdlist1"><code>sessionTimeout</code></dt>
<dd>
<p>The server sends a <code>close</code> event when a client receiving connection have not been seen for a while.
This delay is configured by this setting. By default the <code>close</code> event will be emitted when a receiving
connection wasn&#8217;t seen for 5 seconds.</p>
</dd>
<dt class="hdlist1"><code>heartbeatInterval</code></dt>
<dd>
<p>In order to keep proxies and load balancers from closing long running http
requests we need to pretend that the connection is active and send a heartbeat packet once in a while.
This setting controls how often this is done. By default a heartbeat packet is sent every 25 seconds.</p>
</dd>
<dt class="hdlist1"><code>maxBytesStreaming</code></dt>
<dd>
<p>Most streaming transports save responses on the client side and don&#8217;t free memory used
by delivered messages. Such transports need to be garbage-collected once in a while. <code>max_bytes_streaming</code> sets a
minimum number of bytes that can be send over a single http streaming request before it will be closed. After that
client needs to open new request. Setting this value to one effectively disables streaming and will make streaming
transports to behave like polling transports. The default value is 128K.</p>
</dd>
<dt class="hdlist1"><code>libraryURL</code></dt>
<dd>
<p>Transports which don&#8217;t support cross-domain communication natively ('eventsource' to name one)
use an iframe trick. A simple page is served from the SockJS server (using its foreign domain) and is placed in an
invisible iframe. Code run from this iframe doesn&#8217;t need to worry about cross-domain issues, as it&#8217;s being run from
domain local to the SockJS server. This iframe also does need to load SockJS javascript client library, and this option
lets you specify its url (if you&#8217;re unsure, point it to the latest minified SockJS client release, this is the default).
The default value is <code><a href="http://cdn.jsdelivr.net/sockjs/0.3.4/sockjs.min.js" class="bare">http://cdn.jsdelivr.net/sockjs/0.3.4/sockjs.min.js</a></code></p>
</dd>
<dt class="hdlist1"><code>disabledTransports</code></dt>
<dd>
<p>This is a list of transports that you want to disable. Possible values are
WEBSOCKET, EVENT_SOURCE, HTML_FILE, JSON_P, XHR.</p>
</dd>
</dl>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_sockjs_event_bus_bridge">SockJS event bus bridge</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Vert.x-Web comes with a built-in SockJS socket handler called the event bus bridge which effectively extends the server-side
Vert.x event bus into client side JavaScript.</p>
</div>
<div class="paragraph">
<p>This creates a distributed event bus which not only spans multiple Vert.x instances on the server side, but includes
client side JavaScript running in browsers.</p>
</div>
<div class="paragraph">
<p>We can therefore create a huge distributed bus encompassing many browsers and servers. The browsers don&#8217;t have to
be connected to the same server as long as the servers are connected.</p>
</div>
<div class="paragraph">
<p>This is done by providing a simple client side JavaScript library called <code>vertx-eventbus.js</code> which provides an API
very similar to the server-side Vert.x event-bus API, which allows you to send and publish messages to the event bus
and register handlers to receive messages.</p>
</div>
<div class="paragraph">
<p>This JavaScript library uses the JavaScript SockJS client to tunnel the event bus traffic over SockJS connections
terminating at at a <code><a href="../../yardoc/VertxWeb/SockJSHandler.html">SockJSHandler</a></code> on the server-side.</p>
</div>
<div class="paragraph">
<p>A special SockJS socket handler is then installed on the <code><a href="../../yardoc/VertxWeb/SockJSHandler.html">SockJSHandler</a></code> which
handles the SockJS data and bridges it to and from the server side event bus.</p>
</div>
<div class="paragraph">
<p>To activate the bridge you simply call
<code><a href="../../yardoc/VertxWeb/SockJSHandler.html#bridge-instance_method">bridge</a></code> on the
SockJS handler.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx-web/router'
require 'vertx-web/sock_js_handler'

router = VertxWeb::Router.router(vertx)

sockJSHandler = VertxWeb::SockJSHandler.create(vertx)
options = {
}
sockJSHandler.bridge(options)

router.route("/eventbus/*").handler(&amp;sockJSHandler.method(:handle))</code></pre>
</div>
</div>
<div class="paragraph">
<p>In client side JavaScript you use the 'vertx-eventbus.js` library to create connections to the event bus and to send
and receive messages:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>&lt;script src="http://cdn.jsdelivr.net/sockjs/0.3.4/sockjs.min.js"&gt;&lt;/script&gt;
&lt;script src='vertx-eventbus.js'&gt;&lt;/script&gt;

&lt;script&gt;

var eb = new EventBus('http://localhost:8080/eventbus');

eb.onopen = function() {

  // set a handler to receive a message
  eb.registerHandler('some-address', function(error, message) {
    console.log('received a message: ' + JSON.stringify(message));
  });

  // send a message
  eb.send('some-address', {name: 'tim', age: 587});

}

&lt;/script&gt;</pre>
</div>
</div>
<div class="paragraph">
<p>The first thing the example does is to create a instance of the event bus</p>
</div>
<div class="literalblock">
<div class="content">
<pre>var eb = new EventBus('http://localhost:8080/eventbus');</pre>
</div>
</div>
<div class="paragraph">
<p>The parameter to the constructor is the URI where to connect to the event bus. Since we create our bridge with
the prefix <code>eventbus</code> we will connect there.</p>
</div>
<div class="paragraph">
<p>You can&#8217;t actually do anything with the connection until it is opened. When it is open the <code>onopen</code> handler will be called.</p>
</div>
<div class="paragraph">
<p>You can retrieve the client library using a dependency manager:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Maven (in your <code>pom.xml</code>):</p>
</li>
</ul>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-xml" data-lang="xml">&lt;dependency&gt;
  &lt;groupId&gt;io.vertx&lt;/groupId&gt;
  &lt;artifactId&gt;vertx-web&lt;/artifactId&gt;
  &lt;version&gt;3.3.3&lt;/version&gt;
  &lt;classifier&gt;client&lt;/classifier&gt;
  &lt;type&gt;js&lt;/type&gt;
&lt;/dependency&gt;</code></pre>
</div>
</div>
<div class="ulist">
<ul>
<li>
<p>Gradle (in your <code>build.gradle</code> file):</p>
</li>
</ul>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-groovy" data-lang="groovy">compile 'io.vertx:vertx-web:3.3.3:client'</code></pre>
</div>
</div>
<div class="paragraph">
<p>The library is also available on <a href="https://www.npmjs.com/package/vertx3-eventbus-client">NPM</a> and on
<a href="https://github.com/vert-x3/vertx-bus-bower">Bower</a></p>
</div>
<div class="paragraph">
<p>Notice that the API has changed between the 3.0.0 and 3.1.0 version. Please check the changelog. The previous client
is still compatible and can still be used, but the new client offers more feature and is closer to the vert.x
event bus API.</p>
</div>
<div class="sect2">
<h3 id="_securing_the_bridge">Securing the Bridge</h3>
<div class="paragraph">
<p>If you started a bridge like in the above example without securing it, and attempted to send messages through
it you&#8217;d find that the messages mysteriously disappeared. What happened to them?</p>
</div>
<div class="paragraph">
<p>For most applications you probably don&#8217;t want client side JavaScript being able to send just any message to any
handlers on the server side or to all other browsers.</p>
</div>
<div class="paragraph">
<p>For example, you may have a service on the event bus which allows data to be accessed or deleted. We don&#8217;t want
badly behaved or malicious clients being able to delete all the data in your database!</p>
</div>
<div class="paragraph">
<p>Also, we don&#8217;t necessarily want any client to be able to listen in on any event bus address.</p>
</div>
<div class="paragraph">
<p>To deal with this, a SockJS bridge will by default refuse to let through any messages. It&#8217;s up to you to tell the
bridge what messages are ok for it to pass through. (There is an exception for reply messages which are always allowed through).</p>
</div>
<div class="paragraph">
<p>In other words the bridge acts like a kind of firewall which has a default <em>deny-all</em> policy.</p>
</div>
<div class="paragraph">
<p>Configuring the bridge to tell it what messages it should pass through is easy.</p>
</div>
<div class="paragraph">
<p>You can specify which <em>matches</em> you want to allow for inbound and outbound traffic using the
<code><a href="../dataobjects.html#BridgeOptions">BridgeOptions</a></code> that you pass in when calling bridge.</p>
</div>
<div class="paragraph">
<p>Each match is a <code><a href="../dataobjects.html#PermittedOptions">PermittedOptions</a></code> object:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1"><code><a href="../dataobjects.html#PermittedOptions#set_address-instance_method">address</a></code></dt>
<dd>
<p>This represents the exact address the message is being sent to. If you want to allow messages based on
an exact address you use this field.</p>
</dd>
<dt class="hdlist1"><code><a href="../dataobjects.html#PermittedOptions#set_address_regex-instance_method">addressRegex</a></code></dt>
<dd>
<p>This is a regular expression that will be matched against the address. If you want to allow messages
based on a regular expression you use this field. If the <code>address</code> field is specified this field will be ignored.</p>
</dd>
<dt class="hdlist1"><code><a href="../dataobjects.html#PermittedOptions#set_match-instance_method">match</a></code></dt>
<dd>
<p>This allows you to allow messages based on their structure. Any fields in the match must exist in the
message with the same values for them to be allowed. This currently only works with JSON messages.</p>
</dd>
</dl>
</div>
<div class="paragraph">
<p>If a message is <em>in-bound</em> (i.e. being sent from client side JavaScript to the server) when it is received Vert.x-Web
will look through any inbound permitted matches. If any match, it will be allowed through.</p>
</div>
<div class="paragraph">
<p>If a message is <em>out-bound</em> (i.e. being sent from the server to client side JavaScript) before it is sent to the client
Vert.x-Web will look through any outbound permitted matches. If any match, it will be allowed through.</p>
</div>
<div class="paragraph">
<p>The actual matching works as follows:</p>
</div>
<div class="paragraph">
<p>If an <code>address</code> field has been specified then the <code>address</code> must match <em>exactly</em> with the address of the message
for it to be considered matched.</p>
</div>
<div class="paragraph">
<p>If an <code>address</code> field has not been specified and an <code>addressRegex</code> field has been specified then the regular expression
in <code>address_re</code> must match with the address of the message for it to be considered matched.</p>
</div>
<div class="paragraph">
<p>If a <code>match</code> field has been specified, then also the structure of the message must match. Structuring matching works
by looking at all the fields and values in the match object and checking they all exist in the actual message body.</p>
</div>
<div class="paragraph">
<p>Here&#8217;s an example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx-web/router'
require 'vertx-web/sock_js_handler'

router = VertxWeb::Router.router(vertx)

sockJSHandler = VertxWeb::SockJSHandler.create(vertx)


# Let through any messages sent to 'demo.orderMgr' from the client
inboundPermitted1 = {
  'address' =&gt; "demo.orderMgr"
}

# Allow calls to the address 'demo.persistor' from the client as long as the messages
# have an action field with value 'find' and a collection field with value
# 'albums'
inboundPermitted2 = {
  'address' =&gt; "demo.persistor",
  'match' =&gt; {
    'action' =&gt; "find",
    'collection' =&gt; "albums"
  }
}

# Allow through any message with a field `wibble` with value `foo`.
inboundPermitted3 = {
  'match' =&gt; {
    'wibble' =&gt; "foo"
  }
}

# First let's define what we're going to allow from server -&gt; client

# Let through any messages coming from address 'ticker.mystock'
outboundPermitted1 = {
  'address' =&gt; "ticker.mystock"
}

# Let through any messages from addresses starting with "news." (e.g. news.europe, news.usa, etc)
outboundPermitted2 = {
  'addressRegex' =&gt; "news\\..+"
}

# Let's define what we're going to allow from client -&gt; server
options = {
  'inboundPermitteds' =&gt; [
    inboundPermitted1,
    inboundPermitted1,
    inboundPermitted3
  ],
  'outboundPermitteds' =&gt; [
    outboundPermitted1,
    outboundPermitted2
  ]
}

sockJSHandler.bridge(options)

router.route("/eventbus/*").handler(&amp;sockJSHandler.method(:handle))</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_requiring_authorisation_for_messages">Requiring authorisation for messages</h3>
<div class="paragraph">
<p>The event bus bridge can also be configured to use the Vert.x-Web authorisation functionality to require
authorisation for messages, either in-bound or out-bound on the bridge.</p>
</div>
<div class="paragraph">
<p>To do this, you can add extra fields to the match described in the previous section that determine what authority is
required for the match.</p>
</div>
<div class="paragraph">
<p>To declare that a specific authority for the logged-in user is required in order to access allow the messages you use the
<code><a href="../dataobjects.html#PermittedOptions#set_required_authority-instance_method">requiredAuthority</a></code> field.</p>
</div>
<div class="paragraph">
<p>Here&#8217;s an example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby"># Let through any messages sent to 'demo.orderService' from the client
inboundPermitted = {
  'address' =&gt; "demo.orderService"
}

# But only if the user is logged in and has the authority "place_orders"
inboundPermitted['requiredAuthority'] = "place_orders"

options = {
  'inboundPermitteds' =&gt; [
    inboundPermitted
  ]
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>For the user to be authorised they must be first logged in and secondly have the required authority.</p>
</div>
<div class="paragraph">
<p>To handle the login and actually auth you can configure the normal Vert.x auth handlers. For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx-web/router'
require 'vertx-web/sock_js_handler'
require 'vertx-web/cookie_handler'
require 'vertx-web/local_session_store'
require 'vertx-web/session_handler'
require 'vertx-web/basic_auth_handler'

router = VertxWeb::Router.router(vertx)

# Let through any messages sent to 'demo.orderService' from the client
inboundPermitted = {
  'address' =&gt; "demo.orderService"
}

# But only if the user is logged in and has the authority "place_orders"
inboundPermitted['requiredAuthority'] = "place_orders"

sockJSHandler = VertxWeb::SockJSHandler.create(vertx)
sockJSHandler.bridge({
  'inboundPermitteds' =&gt; [
    inboundPermitted
  ]
})

# Now set up some basic auth handling:

router.route().handler(&amp;VertxWeb::CookieHandler.create().method(:handle))
router.route().handler(&amp;VertxWeb::SessionHandler.create(VertxWeb::LocalSessionStore.create(vertx)).method(:handle))

basicAuthHandler = VertxWeb::BasicAuthHandler.create(authProvider)

router.route("/eventbus/*").handler(&amp;basicAuthHandler.method(:handle))


router.route("/eventbus/*").handler(&amp;sockJSHandler.method(:handle))</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_handling_event_bus_bridge_events">Handling event bus bridge events</h3>
<div class="paragraph">
<p>If you want to be notified when an event occurs on the bridge you can provide a handler when calling
<code><a href="../../yardoc/VertxWeb/SockJSHandler.html#bridge-instance_method">bridge</a></code>.</p>
</div>
<div class="paragraph">
<p>Whenever an event occurs on the bridge it will be passed to the handler. The event is described by an instance of
<code><a href="../../yardoc/VertxWeb/BridgeEvent.html">BridgeEvent</a></code>.</p>
</div>
<div class="paragraph">
<p>The event can be one of the following types:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">SOCKET_CREATED</dt>
<dd>
<p>This event will occur when a new SockJS socket is created.</p>
</dd>
<dt class="hdlist1">SOCKET_CLOSED</dt>
<dd>
<p>This event will occur when a SockJS socket is closed.</p>
</dd>
<dt class="hdlist1">SEND</dt>
<dd>
<p>This event will occur when a message is attempted to be sent from the client to the server.</p>
</dd>
<dt class="hdlist1">PUBLISH</dt>
<dd>
<p>This event will occur when a message is attempted to be published from the client to the server.</p>
</dd>
<dt class="hdlist1">RECEIVE</dt>
<dd>
<p>This event will occur when a message is attempted to be delivered from the server to the client.</p>
</dd>
<dt class="hdlist1">REGISTER</dt>
<dd>
<p>This event will occur when a client attempts to register a handler.</p>
</dd>
<dt class="hdlist1">UNREGISTER</dt>
<dd>
<p>This event will occur when a client attempts to unregister a handler.</p>
</dd>
</dl>
</div>
<div class="paragraph">
<p>The event enables you to retrieve the type using <code><a href="../../yardoc/VertxWeb/BridgeEvent.html#type-instance_method">type</a></code> and
inspect the raw message of the event using <code><a href="../../yardoc/VertxWeb/BridgeEvent.html#get_raw_message-instance_method">getRawMessage</a></code>.</p>
</div>
<div class="paragraph">
<p>The raw message is a JSON object with the following structure:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>{
  "type": "send"|"publish"|"receive"|"register"|"unregister",
  "address": the event bus address being sent/published/registered/unregistered
  "body": the body of the message
}</pre>
</div>
</div>
<div class="paragraph">
<p>The event is also an instance of <code><a href="../../yardoc/Vertx/Future.html">Future</a></code>. When you are finished handling the event you can
complete the future with <code>true</code> to enable further processing.</p>
</div>
<div class="paragraph">
<p>If you don&#8217;t want the event to be processed you can complete the future with <code>false</code>. This is a useful feature that
enables you to do your own filtering on messages passing through the bridge, or perhaps apply some fine grained
authorisation or metrics.</p>
</div>
<div class="paragraph">
<p>Here&#8217;s an example where we reject all messages flowing through the bridge if they contain the word "Armadillos".</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx-web/router'
require 'vertx-web/sock_js_handler'

router = VertxWeb::Router.router(vertx)

# Let through any messages sent to 'demo.orderMgr' from the client
inboundPermitted = {
  'address' =&gt; "demo.someService"
}

sockJSHandler = VertxWeb::SockJSHandler.create(vertx)
options = {
  'inboundPermitteds' =&gt; [
    inboundPermitted
  ]
}

sockJSHandler.bridge(options) { |be|
  if (be.type() == :PUBLISH || be.type() == :RECEIVE)
    if (be.get_raw_message()['body'].==("armadillos"))
      # Reject it
      be.complete(false)
      return
    end
  end
  be.complete(true)
}

router.route("/eventbus").handler(&amp;sockJSHandler.method(:handle))</code></pre>
</div>
</div>
<div class="paragraph">
<p>You can also amend the raw message, e.g. change the body. For messages that are flowing in from the client you can
also add headers to the message, here&#8217;s an example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx-web/router'
require 'vertx-web/sock_js_handler'

router = VertxWeb::Router.router(vertx)

# Let through any messages sent to 'demo.orderService' from the client
inboundPermitted = {
  'address' =&gt; "demo.orderService"
}

sockJSHandler = VertxWeb::SockJSHandler.create(vertx)
options = {
  'inboundPermitteds' =&gt; [
    inboundPermitted
  ]
}

sockJSHandler.bridge(options) { |be|
  if (be.type() == :PUBLISH || be.type() == :SEND)
    # Add some headers
    headers = {
      'header1' =&gt; "val",
      'header2' =&gt; "val2"
    }
    rawMessage = be.get_raw_message()
    rawMessage['headers'] = headers
    be.set_raw_message(rawMessage)
  end
  be.complete(true)
}

router.route("/eventbus").handler(&amp;sockJSHandler.method(:handle))</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_csrf_cross_site_request_forgery">CSRF Cross Site Request Forgery</h2>
<div class="sectionbody">
<div class="paragraph">
<p>CSRF or sometimes also known as XSRF is a technique by which an unauthorized site can gain your user&#8217;s private data.
Vert.x-Web includes a handler <code><a href="../../yardoc/VertxWeb/CSRFHandler.html">CSRFHandler</a></code> that you can use to prevent cross site
request forgery requests.</p>
</div>
<div class="paragraph">
<p>On each get request under this handler a cookie is added to the response with a unique token. Clients are then
expected to return this token back in a header. Since cookies are sent it is required that the cookie handler is also
present on the router.</p>
</div>
<div class="paragraph">
<p>When developing non single page applications that rely on the User-Agent to perform the <code>POST</code> action, Headers cannot
be specified on HTML Forms. In order to solve this problem the header value will also be checked if and only if no
header was present in the Form attributes under the same name as the header, e.g.:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-html" data-lang="html">---
&lt;form action="/submit" method="POST"&gt;
&lt;input type="hidden" name="X-XSRF-TOKEN" value="abracadabra"&gt;
&lt;/form&gt;
---</code></pre>
</div>
</div>
<div class="paragraph">
<p>It is the responsibility of the user to fill in the right value for the form field. Users who prefer to use an HTML
only solution can fill this value by fetching the the token value from the routing context under the key <code>X-XSRF-TOKEN</code>
or the header name they have chosen during the instantiation of the <code>CSRFHandler</code> object.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx-web/cookie_handler'
require 'vertx-web/csrf_handler'

router.route().handler(&amp;VertxWeb::CookieHandler.create().method(:handle))
router.route().handler(&amp;VertxWeb::CSRFHandler.create("abracadabra").method(:handle))
router.route().handler() { |rc|

}</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_virtualhost_handler">VirtualHost Handler</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The Virtual Host Handler will verify the request hostname and if it matches it will send the request to the
registered handler, otherwise will continue inside the normal handlers chain.</p>
</div>
<div class="paragraph">
<p>Request are checked against the <code>Host</code> header to a match and patterns allow the usage of <code><strong></code> wildcards, as for
example <code></strong>.vertx.io</code> or fully domain names as <code>www.vertx.io</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx-web/virtual_host_handler'
router.route().handler(&amp;VertxWeb::VirtualHostHandler.create("*.vertx.io") { |routingContext|
  # do something if the request is for *.vertx.io
}.method(:handle))</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_oauth2authhandler_handler">OAuth2AuthHandler Handler</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The <code>OAuth2AuthHandler</code> allows quick setup of secure routes using the OAuth2 protocol. This handler simplifies the
authCode flow. An example of using it to protect some resource and authenticate with GitHub can be implemented as:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx-auth-oauth2/o_auth2_auth'
require 'vertx-web/o_auth2_auth_handler'

# create an OAuth2 provider, clientID and clientSecret should be requested to github
authProvider = VertxAuthOauth2::OAuth2Auth.create(vertx, :AUTH_CODE, {
  'clientID' =&gt; "CLIENT_ID",
  'clientSecret' =&gt; "CLIENT_SECRET",
  'site' =&gt; "https://github.com/login",
  'tokenPath' =&gt; "/oauth/access_token",
  'authorizationPath' =&gt; "/oauth/authorize"
})

# create a oauth2 handler on our domain: "http://localhost:8080"
oauth2 = VertxWeb::OAuth2AuthHandler.create(authProvider, "http://localhost:8080")

# setup the callback handler for receiving the GitHub callback
oauth2.setup_callback(router.get("/callback"))

# protect everything under /protected
router.route("/protected/*").handler(&amp;oauth2.method(:handle))
# mount some handler under the protected zone
router.route("/protected/somepage").handler() { |rc|
  rc.response().end("Welcome to the protected resource!")
}

# welcome page
router.get("/").handler() { |ctx|
  ctx.response().put_header("content-type", "text/html").end("Hello&lt;br&gt;&lt;a href=\"/protected/somepage\"&gt;Protected by Github&lt;/a&gt;")
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The OAuth2AuthHandler will setup a proper callback OAuth2 handler so the user does not need to deal with validation
of the authority server response. It is quite important to know that authority server responses are only valid once,
this means that if a client issues a reload of the callback URL it will be asserted as a invalid request since the
validation will fail.</p>
</div>
<div class="paragraph">
<p>A rule of thumb is once a valid callback is executed issue a client side redirect to a protected resource. This
redirect should also create a session cookie (or other session mechanism) so the user is not required to authenticate
for every request.</p>
</div>
<div class="paragraph">
<p>Due to the nature of OAuth2 spec there are slight changes required in order to use other OAuth2 providers, for
example, if you are planning to use Google Auth you implement it as:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx-auth-oauth2/o_auth2_auth'
require 'vertx-web/o_auth2_auth_handler'

# create an OAuth2 provider, clientID and clientSecret should be requested to Google
authProvider = VertxAuthOauth2::OAuth2Auth.create(vertx, :AUTH_CODE, {
  'clientID' =&gt; "CLIENT_ID",
  'clientSecret' =&gt; "CLIENT_SECRET",
  'site' =&gt; "https://accounts.google.com",
  'tokenPath' =&gt; "https://www.googleapis.com/oauth2/v3/token",
  'authorizationPath' =&gt; "/o/oauth2/auth"
})

# create a oauth2 handler on our domain: "http://localhost:8080"
oauth2 = VertxWeb::OAuth2AuthHandler.create(authProvider, "http://localhost:8080")

# these are the scopes
oauth2.add_authority("profile")

# setup the callback handler for receiving the Google callback
oauth2.setup_callback(router.get("/callback"))

# protect everything under /protected
router.route("/protected/*").handler(&amp;oauth2.method(:handle))
# mount some handler under the protected zone
router.route("/protected/somepage").handler() { |rc|
  rc.response().end("Welcome to the protected resource!")
}

# welcome page
router.get("/").handler() { |ctx|
  ctx.response().put_header("content-type", "text/html").end("Hello&lt;br&gt;&lt;a href=\"/protected/somepage\"&gt;Protected by Google&lt;/a&gt;")
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The changes are only on the configuration, note that the token uri must now be a full URL since it is generated from
a different server than the authorization one.</p>
</div>
<div class="paragraph">
<p>Important to note that for google OAuth you must register all your callback URLs in the developer console, so for the
current example you would need to register <code><a href="http://localhost:8080/callback?redirect_uri=/protected/somepage" class="bare">http://localhost:8080/callback?redirect_uri=/protected/somepage</a></code>.</p>
</div>
<div class="paragraph">
<p>If you&#8217;re looking to integrate with LinkedIn then your config should be:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx-auth-oauth2/o_auth2_auth'
require 'vertx-web/o_auth2_auth_handler'

# create an OAuth2 provider, clientID and clientSecret should be requested to LinkedIn
authProvider = VertxAuthOauth2::OAuth2Auth.create(vertx, :AUTH_CODE, {
  'clientID' =&gt; "CLIENT_ID",
  'clientSecret' =&gt; "CLIENT_SECRET",
  'site' =&gt; "https://www.linkedin.com",
  'authorizationPath' =&gt; "/uas/oauth2/authorization",
  'tokenPath' =&gt; "/uas/oauth2/accessToken"
})

# create a oauth2 handler on our domain: "http://localhost:8080"
oauth2 = VertxWeb::OAuth2AuthHandler.create(authProvider, "http://localhost:8080")

# these are the scopes
oauth2.add_authority("r_basicprofile")

# setup the callback handler for receiving the LinkedIn callback
oauth2.setup_callback(router.get("/callback"))

# protect everything under /protected
router.route("/protected/*").handler(&amp;oauth2.method(:handle))
# mount some handler under the protected zone
router.route("/protected/somepage").handler() { |rc|
  rc.response().end("Welcome to the protected resource!")
}

# welcome page
router.get("/").handler() { |ctx|
  ctx.response().put_header("content-type", "text/html").end("Hello&lt;br&gt;&lt;a href=\"/protected/somepage\"&gt;Protected by LinkedIn&lt;/a&gt;")
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>As it can be seen from the examples all you need to know is 2 urls, the authorization path and the token path. You
will find all these configurations on your provider documentation we have also listed on the auth project examples
for:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>google</p>
</li>
<li>
<p>twitter</p>
</li>
<li>
<p>github</p>
</li>
<li>
<p>linkedin</p>
</li>
<li>
<p>facebook</p>
</li>
<li>
<p>keycloak</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>For keycloak we have a slighter easier setup, just export the json file from the keycloak admin console and load it
into the handler. Keycloak has some differences from the other providers in the sense that it can also use the token
to specify grants. You can validate against these grants like this:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-ruby" data-lang="ruby">require 'vertx-auth-oauth2/o_auth2_auth'
require 'vertx-web/o_auth2_auth_handler'
# create an OAuth2 provider for keycloak
authProvider = VertxAuthOauth2::OAuth2Auth.create_keycloak(vertx, :AUTH_CODE, {
})

# create a oauth2 handler on our domain: "http://localhost:8000"
oauth2 = VertxWeb::OAuth2AuthHandler.create(authProvider, "http://localhost:8000")

# setup the callback handler for receiving the keycloak callback
oauth2.setup_callback(router.get("/callback"))

# protect everything under /protected
router.route("/protected/*").handler(&amp;oauth2.method(:handle))

# mount some handler under the protected zone
router.route("/protected/somepage").handler() { |rc|
  # you can now do authZ based on keycloak grants
  rc.user().is_authorised("account:manage-account") { |manageAccount_err,manageAccount|
    if (manageAccount)
      rc.response().end("Welcome to the protected resource and you can manage your account!")
    else
      rc.response().end("Welcome to the protected resource but you cannot manage your account!")
    end
  }
}

# welcome page
router.get("/").handler() { |ctx|
  ctx.response().put_header("content-type", "text/html").end("Hello&lt;br&gt;&lt;a href=\"/protected/somepage\"&gt;Protected by keycloak&lt;/a&gt;")
}</code></pre>
</div>
</div>
</div>
</div>

        

        
          <div id="footer">
            <div id="footer-text">
              
                Last updated 2016-09-12 08:38:04 CEST
              
              
            </div>
          </div>
        
      </div>
    </div>
  </div>
</div>

<footer>
  <div class="container">
    <div class="row">
      <div class="col-xs-6 col-sm-3 col-md-3 col-lg-2">
        <h2>Vert.x</h2>
        <ul class="list-unstyled">
          <li><a href="http://vertx.io/">Home</a></li>
          <li><a href="http://vertx.io/download/">Download</a></li>
          <li><a href="http://vertx.io/docs/">Documentation</a></li>
          <li><a href="https://github.com/vert-x3/wiki/wiki">Wiki</a></li>
          <li><a href="http://vertx.io/blog/">Blog</a></li>
          <li><a href="http://vertx.io/vertx2/" class="vertx-2-link">Vert.x 2</a></li>
        </ul>
      </div>
      <div class="col-xs-6 col-sm-3 col-md-3 col-lg-2">
        <h2>Community</h2>
        <ul class="list-unstyled">
          <li><a href="http://vertx.io/community/">Help &amp; Contributors</a></li>
          <li><a href="http://vertx.io/materials/">Learning materials</a></li>
          <li><a href="https://groups.google.com/forum/?fromgroups#!forum/vertx">User Group</a></li>
          <li><a href="https://groups.google.com/forum/?fromgroups#!forum/vertx-dev">Developer Group</a></li>
        </ul>
      </div>

      <div class="col-xs-12 col-sm-6 col-lg-offset-2 col-md-6 copyright">
        <p>Vert.x is open source and dual licensed under the <a href="https://www.eclipse.org/org/documents/epl-v10.php">Eclipse Public License 1.0</a> and <a href="https://www.apache.org/licenses/LICENSE-2.0.html">Apache License 2.0</a>.</p>
        <p>This website is licensed under the <a href="http://creativecommons.org/licenses/by-sa/3.0/">CC BY-SA 3.0 License</a>.<br>
        Design by <a href="http://www.michel-kraemer.com">Michel Kr&auml;mer</a>. <a href="http://www.entypo.com">Entypo pictograms</a> by Daniel Bruce.</p>
        <div class="row">
          <div class="col-xs-12 col-lg-offset-1 col-md-5">
            <a href="http://eclipse.org">
            <img class="logo eclipse-logo" src="http://vertx.io/assets/eclipse_logo_grey_small.png" width="204" height="48">
            </a>
          </div>
          <div class="col-xs-12 col-md-offset-2 col-lg-offset-0 col-md-5">
            <a href="http://cloudbees.com">
            <img class="logo cloudbees-logo" src="http://vertx.io/assets/Button-Built-on-CB-1-grey.png" width="180" height="48">
           </a>
          </div>
          <div class="col-xs-12 col-md-offset-2 col-lg-offset-1 col-md-5 jprofiler">
            <a href="http://www.ej-technologies.com/products/jprofiler/overview.html"
            style="text-decoration:none">
            <img class="logo jprofiler-logo" src="http://vertx.io/assets/jprofiler-logo.png" width="48" height="48"><span class="jprofiler-logo">&nbsp; JPROFILER</span>
            </a>
          </div>
        </div>
      </div>
    </div>
  </div>
</footer>

<script src="http://static.jboss.org/theme/js/libs/jquery/jquery-1.9.1.min.js"></script>
<script src="http://vertx.io/javascripts/bootstrap.min.js"></script>
<script src="http://vertx.io/javascripts/highlight.pack.js"></script>
<script>hljs.initHighlightingOnLoad();</script>



<script src="http://vertx.io/javascripts/sidebar.js"></script>


</body>
</html>
